先看效果图
轮播组件banner
属性
list:banner数据,格式:[{"title":"中国卫星","imgUrl":"https://gimg3.baidu.png"},{"title":"美国卫星","imgUrl":"https://gimg3.baidu.png"},{"title":"俄罗斯卫星","imgUrl":"https://gimg3.baidu.png"}],可以添加与title平级的数据,比如说:{"title":"中国卫星","imgUrl":"https://gimg3.baidu.png","link":"https://xxxxxxxx"}
bannerWidth:轮播图的宽度,String类型,例如 '100px' ,'100rpx', '100vw'等
bannerHeight:轮播图高度,类型如上
bannerInterval:滑动动画时长,Number类型, 单位毫秒,默认5秒
bannerDuration:banner 滑动动画时长,Number类型,单位毫秒,默认500毫秒 (app-nvue不支持)
bannerAutoPlay: banner是否自动切换, Boolean类型, 默认true
bannerCircular:banner是否才用衔接滑动(即播放到末尾后重新回到开头),Boolean类型,默认true
bannerVertical:banner滑动方向是否为纵向,Boolean类型,默认false
bannerPreviousMargin:banner前边距(可用于露出前一项的一小部分,接受 px 和 rpx 值),String类型,默认没有为'0px',(app-nvue、字节跳动小程序、飞书小程序不支持)
bannerNextMargin:banner后边距 (可用于露出前一项的一小部分,接受 px 和 rpx 值),String类型,默认没有为'0px‘,(app-nvue、字节跳动小程序、飞书小程序不支持)
事件
onBannerClick:banner的条目点击事件,接收到的值为当前所处的位置index,类型Number
使用方法:
<banner :list="bannerList" @onBannerClick="onBannerClick"></banner>
然后以上属性可以按需修改
具体代码:
子组件banner
<!-- 轮播图 -->
<template>
<view class="banner-view" :style="{width:bannerWidth,height:bannerHeight}">
<swiper
:style="{width:bannerWidth,height:bannerHeight}"
:autoplay="bannerAutoPlay"
:interval="bannerInterval"
:duration="bannerDuration"
:circular="bannerCircular"
:vertical="bannerVertical"
:previous-margin="bannerPreviousMargin"
:next-margin="bannerNextMargin"
@change="onBannerChange">
<swiper-item v-for="(item,index) in list" :key='index' @click="onBannerClick">
<!-- 动态绑定src -->
<image :src="item.imgUrl" :style="{width:bannerWidth,height:bannerHeight}"></image>
</swiper-item>
</swiper>
<view class="title-view">
<text class="title-text">
{{list[currentIndex].title}}
</text>
<text class="index-text">
{{currentIndex + 1 + '/' + list.length}}
</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
currentIndex: 0
}
},
props: {
list: { // banner数据 ,格式[{"title":"111","imgUrl":"http://www.xxxxxxxxxx.jpg"}]
type: Array,
default () {
return [];
}
},
bannerWidth: { // banner高度,默认全屏宽 750rpx
type: String,
default: '750rpx'
},
bannerHeight: { // banner高度,默认高度为宽度的一半
type: String,
default: '375rpx'
},
bannerInterval: { // banner自动切换时间 单位毫秒,默认5秒
type: Number,
default: 5000
},
bannerDuration: { // banner 滑动动画时长 单位毫秒,默认500毫秒 (app-nvue不支持)
type: Number,
default: 500
},
bannerAutoPlay: { // banner是否自动切换 默认true
type: Boolean,
default: true
},
bannerCircular: { // banner是否才用衔接滑动(即播放到末尾后重新回到开头),默认true
type: Boolean,
default: true
},
bannerVertical: { // banner滑动方向是否为纵向,默认false
type: Boolean,
default: false
},
bannerPreviousMargin: { // banner前边距(可用于露出前一项的一小部分,接受 px 和 rpx 值),默认没有 (app-nvue、字节跳动小程序、飞书小程序不支持)
type: String,
default: '0px'
},
bannerNextMargin: { // banner后边距 (可用于露出前一项的一小部分,接受 px 和 rpx 值),默认没有 (app-nvue、字节跳动小程序、飞书小程序不支持)
type: String,
default: '0px'
}
},
methods: {
// banner 切换监听
onBannerChange(e) {
this.currentIndex = e.detail.current;
},
// banner 点击事件
onBannerClick() {
// 通知父组件 点击事件,传值当前index
this.$emit("onBannerClick", this.currentIndex)
}
}
}
</script>
<style>
.banner-view {
position: relative;
}
.title-view {
width: 100%;
height: 70rpx;
background: linear-gradient(#00000060, #000000c0);
position: absolute;
bottom: 0;
display: inline-block;
}
text {
color: white;
line-height: 70rpx;
display: inline-block;
margin: 0 30rpx;
}
.index-text {
position: absolute;
right: 0;
}
</style>
父组件使用
<template>
<view>
<banner :list="bannerList" @onBannerClick="onBannerClick"></banner>
</view>
</template>
<script>
import banner from '../../../components/banner.vue'
export default {
components: {
banner
},
data() {
return {
bannerList: [{
"title": "中国卫星",
"imgUrl": "https://gimg3.baidu.com/search/src=http%3A%2F%2Fpics6.baidu.com%2Ffeed%2F267f9e2f070828389bcfc97b6a2a0a084e08f1d8.jpeg%3Ftoken%3D17721a9b2fb70d8459c77d077f3a3a78&refer=http%3A%2F%2Fwww.baidu.com&app=2021&size=f360,240&n=0&g=0n&q=75&fmt=auto?sec=1640797200&t=f0c8a3aa2beef7b2849c2c8052340666"
},
{
"title": "美国卫星",
"imgUrl": "https://gimg3.baidu.com/search/src=http%3A%2F%2Fpics7.baidu.com%2Ffeed%2F72f082025aafa40fb3d37d7f7bd7a04679f019bc.jpeg%3Ftoken%3Df82c6772c21b85d89c21910e822847cc&refer=http%3A%2F%2Fwww.baidu.com&app=2021&size=f360,240&n=0&g=0n&q=75&fmt=auto?sec=1640797200&t=44c9403edc013348b6c9992d4d1c51dc"
},
{
"title": "俄罗斯卫星",
"imgUrl": "https://gimg3.baidu.com/search/src=http%3A%2F%2Fpics7.baidu.com%2Ffeed%2F7dd98d1001e9390190f2ee6da95ff7ee37d1962a.jpeg%3Ftoken%3Dd94177a7a6be5a9550d9dad8f7704334&refer=http%3A%2F%2Fwww.baidu.com&app=2021&size=f360,240&n=0&g=0n&q=75&fmt=auto?sec=1640797200&t=2c430fe85ce8ee866b69af57c11c1d46"
}
]
}
},
methods: {
onBannerClick(index) {
console.log('点击了' + index);
}
}
}
</script>
<style>
</style>
遗留问题
有两个问题没解决,
1:就是滑动或者是点击底部title-view,不会生效的问题,原因是title-view和swiper这两个组件是平级关系:。
2:就是当轮播图不显示或者滑动到其他页面不显示在前台时(组件是没有onShow和onHide生命周期的),这时候要关闭自动轮播,然后显示的时候再打开自动轮播。
后续的话会再看怎么去解决,如果已经解决的同学欢迎评论区留言。
遗留问题解决
第2个问题解决方法:使用vuex全局变量,然后废除上面的自定义属性bannerAutoPlay,使用全局的变量,在banner所属页面的生命周期方法onShow和onHide中去修改这个值,最后在banner组件中取得这个值来赋值给autoplay属性。