vue 一个简单的项目 之三 详情页面 step2 公用组件画廊组件

上篇,我们实现了详情页面的顶部的样式。本篇我们来实现一个公用组件 —— 画廊组件。

画廊组件,就是不会自动轮播的轮播组件。由于项目可能在很多地方需要使用到,因此,我们把它写成公用组件。

打开项目,在src 目录下,创建一个common 文件夹,在这个文件夹下存放一些公用的组件。

好啦,再在common 目录下,创建文件夹 gallery ,在gallery 目录下,创建文件Gallary.vue 。

初始化一下 Gallary.vue 如下。

<template>
  <div>gallary</div>
</template>

<script>
export default {
  name: 'CommonGallary'
}
</script>

<style lang='stylus' scoped>

</style>

接下来,我们要在build 目录下, webpack.base.cong.js 中,写一段代码。如下, 在别名里面加一项common 的别名。

module.exports = {
  context: path.resolve(__dirname, '../'),
  entry: {
    app: './src/main.js'
  },
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  },
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
      'styles': resolve('src/assets/styles'),
      'common': resolve('src/common'),
    }
  },

保存后,重启服务器。

然后,我们在detail/components 下的 Banner.vue 中去使用新定义的Gallary.vue 组件。Banner.vue 相关代码如下。

<template>
  <div>
    <div class="banner">
      <img class="banner-img" src="https://dimg07.c-ctrip.com/images/w30k0o000000esrxi8010.jpg_Z_800_600.jpg">
      <div class="banner-info">
        <div class="banner-title">
          孔雀蓝天空
        </div>
        <div class="banner-number">
          <span class="iconfont banner-icon">&#xe632;</span>
          100
        </div>
      </div>
    </div>
    <common-gallary></common-gallary>
  </div>
</template>

<script>
import CommonGallary from 'common/gallary/Gallary'
export default {
  name: 'DetailBanner',
  components: {
    CommonGallary
  }
}
</script>

好啦,我们来写 Gallary.vue 的样式。如下。我们做好了两个图片的滑动。

<template>
  <div class="container">
    <div class="wrapper">
      <swiper>
        <swiper-slide >
          <img class="gallary-img" src="https://dimg07.c-ctrip.com/images/w30q0o000000eq7z17747.jpg_Z_800_600.jpg" />
        </swiper-slide>
        <swiper-slide >
          <img class="gallary-img" src="https://dimg07.c-ctrip.com/images/w3060o000000ep39r71C6.jpg_Z_800_600.jpg" />
        </swiper-slide>
        <!-- <div class="swiper-pagination"  slot="pagination"></div> -->
      </swiper>
    </div>
  </div>
</template>

<script>
export default {
  name: 'CommonGallary'
}
</script>

<style lang='stylus' scoped>
  .container
    display: flex
    flex-direction: column
    justify-content: center
    position: fixed
    left: 0
    right: 0
    top: 0
    bottom: 0
    background: #000
    z-index: 99
    .wrapper
      background: #fff
      overflow: hidden
      height: 0
      width: 100%
      padding-bottom: 66.125%
      .gallary-img
        width: 100%
</style>

下面,我们加入当前页面在整个画廊中的次序的提示。我们使用的轮播插件,实际上底层使用的是swiper3。因此去swiper3 官网上,查看 paginationType 的属性,可以对我们设置插件值有帮助。如下。

<template>
  <div class="container">
    <div class="wrapper">
      <swiper :options="swiperOptions">
        <swiper-slide >
          <img class="gallary-img" src="https://dimg07.c-ctrip.com/images/w30q0o000000eq7z17747.jpg_Z_800_600.jpg" />
        </swiper-slide>
        <swiper-slide >
          <img class="gallary-img" src="https://dimg07.c-ctrip.com/images/w3060o000000ep39r71C6.jpg_Z_800_600.jpg" />
        </swiper-slide>
        <div class="swiper-pagination"  slot="pagination"></div>
      </swiper>
    </div>
  </div>
</template>

<script>
export default {
  name: 'CommonGallary',
  data () {
    return {
      swiperOptions: {
        pagination: '.swiper-pagination',
        paginationType: 'fraction'
      }
    }
  }
}
</script>

<style lang='stylus' scoped>
  .container >>> .swiper-container
    overflow: inherit
  .container
    display: flex
    flex-direction: column
    justify-content: center
    position: fixed
    left: 0
    right: 0
    top: 0
    bottom: 0
    background: #000
    z-index: 99
    .wrapper
      background: #fff
      height: 0
      width: 100%
      padding-bottom: 66.125%
      .gallary-img
        width: 100%
      .swiper-pagination
        color: #fff
        bottom: -1rem
</style>

下面,我们做逻辑部分。

首先img 的src 是从父组件获取的,如下,先是父组件,然后是Gallary.vue 组件

<template>
  <div>
    <div class="banner">
      <img class="banner-img" src="https://dimg07.c-ctrip.com/images/w30k0o000000esrxi8010.jpg_Z_800_600.jpg">
      <div class="banner-info">
        <div class="banner-title">
          孔雀蓝天空
        </div>
        <div class="banner-number">
          <span class="iconfont banner-icon">&#xe632;</span>
          100
        </div>
      </div>
    </div>
    <common-gallary :imgs="imgs"></common-gallary>
  </div>
</template>

<script>
import CommonGallary from 'common/gallary/Gallary'
export default {
  name: 'DetailBanner',
  data () {
    return {
      imgs: ['https://dimg07.c-ctrip.com/images/w30q0o000000eq7z17747.jpg_Z_800_600.jpg',
        'https://dimg07.c-ctrip.com/images/w3060o000000ep39r71C6.jpg_Z_800_600.jpg']
    }
  },
  components: {
    CommonGallary
  }
}
</script>
<template>
  <div class="container">
    <div class="wrapper">
      <swiper :options="swiperOptions">
        <swiper-slide
          v-for="(item,index) in imgs"
          :key="index"
        >
          <img class="gallary-img"
            :src="item" />
        </swiper-slide>
        <div class="swiper-pagination"  slot="pagination"></div>
      </swiper>
    </div>
  </div>
</template>

<script>
export default {
  name: 'CommonGallary',
  props: {
    imgs: {
      type: Array,
      default () {
        return []
      }
    }
  },
  data () {
    return {
      swiperOptions: {
        pagination: '.swiper-pagination',
        paginationType: 'fraction'
      }
    }
  }
}
</script>

好啦,然后再在父组件Banner.vue 中控制画廊控件的显示。

Banner.vue 关联代码如下。

<template>
  <div>
    <div class="banner" @click="handleBannerClick">
      <img class="banner-img" src="https://dimg07.c-ctrip.com/images/w30k0o000000esrxi8010.jpg_Z_800_600.jpg">
      <div class="banner-info">
        <div class="banner-title">
          孔雀蓝天空
        </div>
        <div class="banner-number">
          <span class="iconfont banner-icon">&#xe632;</span>
          100
        </div>
      </div>
    </div>
    <common-gallary :imgs="imgs" v-show="showGallary"></common-gallary>
  </div>
</template>

<script>
import CommonGallary from 'common/gallary/Gallary'
export default {
  name: 'DetailBanner',
  data () {
    return {
      showGallary: false,
      imgs: ['https://dimg07.c-ctrip.com/images/w30q0o000000eq7z17747.jpg_Z_800_600.jpg',
        'https://dimg07.c-ctrip.com/images/w3060o000000ep39r71C6.jpg_Z_800_600.jpg']
    }
  },
  components: {
    CommonGallary
  },
  methods: {
    handleBannerClick () {
      this.showGallary = true
    }
  }
}
</script>

这时候,会发现画廊滑动会有一些问题。这是因为插件,隐藏后显示,在width 上会有点儿问题,给插件,配两个参数即可。(父元素变了后会自动刷新)。如下,Gallary.vue 。

<script>
export default {
  name: 'CommonGallary',
  props: {
    imgs: {
      type: Array,
      default () {
        return []
      }
    }
  },
  data () {
    return {
      swiperOptions: {
        pagination: '.swiper-pagination',
        paginationType: 'fraction',
        observeParents: true,
        observer: true
      }
    }
  }
}
</script>

最后,在Gallary.vue 中控制画廊的关闭。如下,子组件的click 事件,发布一个close,父组件,接收到后进行处理。

子组件代码

<template>
  <div class="container" @click="handleGalleryClick">
    <div class="wrapper">
      <swiper :options="swiperOptions">
        <swiper-slide
          v-for="(item,index) in imgs"
          :key="index"
        >
          <img class="gallary-img"
            :src="item" />
        </swiper-slide>
        <div class="swiper-pagination"  slot="pagination"></div>
      </swiper>
    </div>
  </div>
</template>

<script>
export default {
  name: 'CommonGallary',
  props: {
    imgs: {
      type: Array,
      default () {
        return []
      }
    }
  },
  data () {
    return {
      swiperOptions: {
        pagination: '.swiper-pagination',
        paginationType: 'fraction',
        observeParents: true,
        observer: true
      }
    }
  },
  methods: {
    handleGalleryClick () {
      this.$emit('close')
    }
  }
}
</script>

父组件代码

<template>
  <div>
    <div class="banner" @click="handleBannerClick">
      <img class="banner-img" src="https://dimg07.c-ctrip.com/images/w30k0o000000esrxi8010.jpg_Z_800_600.jpg">
      <div class="banner-info">
        <div class="banner-title">
          孔雀蓝天空
        </div>
        <div class="banner-number">
          <span class="iconfont banner-icon">&#xe632;</span>
          100
        </div>
      </div>
    </div>
    <common-gallary
      :imgs="imgs"
      v-show="showGallary"
      @close="handleGalleryClose"
    ></common-gallary>
  </div>
</template>

<script>
import CommonGallary from 'common/gallary/Gallary'
export default {
  name: 'DetailBanner',
  data () {
    return {
      showGallary: false,
      imgs: ['https://dimg07.c-ctrip.com/images/w30q0o000000eq7z17747.jpg_Z_800_600.jpg',
        'https://dimg07.c-ctrip.com/images/w3060o000000ep39r71C6.jpg_Z_800_600.jpg']
    }
  },
  components: {
    CommonGallary
  },
  methods: {
    handleBannerClick () {
      this.showGallary = true
    },
    handleGalleryClose () {
      this.showGallary = false
    }
  }
}
</script>

好啦,可以提交合并啦。

猜你喜欢

转载自blog.csdn.net/purple_lumpy/article/details/85011944