上篇,我们实现了详情页面的顶部的样式。本篇我们来实现一个公用组件 —— 画廊组件。
画廊组件,就是不会自动轮播的轮播组件。由于项目可能在很多地方需要使用到,因此,我们把它写成公用组件。
打开项目,在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"></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"></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"></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"></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>
好啦,可以提交合并啦。