uniapp:自定义一个轮播图组件

本文介绍了如何在Vue中创建一个自定义轮播Banner组件,详细解析了组件的属性和事件,包括轮播数据、宽度、高度、动画时长等配置,并展示了组件的模板结构和样式。同时,提出了两个遗留问题:标题视图的交互问题以及自动轮播在组件隐藏时的控制。对于第二个问题,提出了使用Vuex全局状态管理的解决方案。
摘要由CSDN通过智能技术生成

先看效果图

轮播组件banner

属性

listbanner数据,格式:[{"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属性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值