uniapp-无缝轮播

在uniapp中有个轮播组件swiper,虽然实现了轮播大部分功能,要弄无缝轮播 只要添加个 circular 就可以实现无缝轮播,虽然框架好用,但我们也要知道他怎么写的  就自己随便造了轮子

<template>
	<view class="banner-main">
		<view class="banner" :style="{ height: height + 'rpx' }">
			<view
				class="banner-bg-box"
				:class="Trans ? 'Trans' : ''"
				:style="{ left: -(current * elementW) + 'px', width: boxWidth + 'px' }"
				@touchstart="touchstart"
				@touchmove="touchmove"
				@touchend="touchend"
			>
				<slot><image class="banner-bg" :src="item.image.path" v-for="(item, index) in list" :key="index"></image></slot>
			</view>
			<view class="dots" v-if="indicatorDots"><text :class="index == current ? 'active' : ''" v-for="index in banner.length - 2" :key="index"></text></view>
		</view>
	</view>
</template>

<script>
export default {
	data() {
		return {
			startX: 0, //触摸开始位置
			moveX: 0, //移动的位置
			elementW: 0, //元素的宽度
			transLeft: 0, //位移距离
			boxWidth: 9999, //盒子的宽度
			Trans: false,
			current: 1,
			timer: null, //定时器
			frequency: 0, //次数
			list: [] //轮播数据
		};
	},
	props: {
		banner: {
			type: Array,
			default() {
				return [];
			}
		},
		index: {
			type: [String, Number],
			default: 1
		}, //下标
		autoplay: {
			type: Boolean,
			default: true
		},
		time: {
			type: [String, Number],
			default: 3000
		},
		height: {
			type: [String, Number],
			default: 279
		},
		'indicatorDots': {
			type: Boolean,
			default: true
		}
	},
	mounted() {
		this.setConfig();
	},
	watch: {
		banner(val) {
			if (this.frequency < 1 && this.list.length == 0) {
				this.frequency++;
				this.hanldData();
				this.setConfig();
			}
		}
	},
	methods: {
		hanldData() {
			let banner = this.banner;
			let leng = banner.length - 1;
			let homeBanner = banner[0],
				lastBanner = banner[leng];
			banner.unshift(lastBanner);
			banner.push(homeBanner);
			this.list = banner;
		},
		setConfig() {
			const that = this;
			if (that.banner.length != 0) {
				if (this.list.length == 0) {
					this.hanldData();
					this.setConfig();
				} else {
					/* 获取下标 */
					that.current = that.index || 1;
					/* 计算banner宽度 */
					this.elementW = uni.upx2px(690);
					that.Trans = false;
					that.transLeft = that.elementW * that.current;
					that.boxWidth = that.list.length * that.elementW;
					/* 添加过度效果 */
					let timer = null;
					clearTimeout(timer);
					timer = setTimeout(function() {
						that.Trans = true;
						/* 是否开启自动轮播 */
						if (that.autoplay) {
							that.auto();
						}
					}, 300);
				}
			}
		},
		/* 开始触摸 */
		touchstart(e) {
			const touches = e.touches[0];
			let clientX = touches.clientX,
				clientY = touches.clientY;
			this.startX = clientX;
			clearInterval(this.timer);
		},
		/* 触摸移动 */
		touchmove(e) {
			const touches = e.touches[0];
			let clientX = touches.clientX,
				clientY = touches.clientY;
			this.moveX = clientX;
		},
		/* 触摸结束 */
		touchend(e) {
			if (this.moveX - this.startX > 0) {
				//向右滑动
				this.sliderRight();
			} else {
				//向左滑动
				this.sliderLeft();
			}
			this.changeCurrent();
			if (this.autoplay) {
				this.auto();
			}
		},
		changeCurrent() {
			this.$emit('change', this.current);
		},
		sliderLeft() {
			const that = this;
			this.current++;
			this.Trans = true;
			if (this.current >= this.list.length - 1) {
				this.Trans = false;
				this.current = 0;
				setTimeout(() => {
					this.current++;
					this.Trans = true;
				}, 30);
			}
		},
		sliderRight() {
			const that = this;
			this.current--;
			this.Trans = true;
			if (this.current <= 0) {
				this.Trans = false;
				this.current = this.list.length - 1;
				setTimeout(() => {
					that.Trans = true;
					that.current--;
				}, 30);
			}
		},
		auto() {
			const that = this;
			that.timer = null;
			clearInterval(that.timer);
			that.timer = setInterval(() => {
				that.sliderLeft();
			}, that.time);
		}
	}
};
</script>

<style lang="scss" scoped>
.banner {
	width: 690rpx;
	height: 279rpx;
	background-position: 690rpx 0;
	position: relative;
	overflow: hidden;
	border-radius: 10rpx;
	position: relative;
	.banner-bg-box {
		height: 100%;
		position: absolute;
		top: 0;
		left: 690rpx;
		transition: none;
		&.Trans {
			transition: all 1s;
		}
		.banner-bg {
			width: 690rpx;
			height: 100%;
			float: left;
		}
	}
	.dots {
		position: absolute;
		left: 50%;
		bottom: 0rpx;
		transform: translateX(-50%);
		text {
			display: inline-block;
			width: 20rpx;
			height: 20rpx;
			background: #ccc;
			margin: 0 5rpx;
			border-radius: 50%;
			&.active {
				background: $main-color;
			}
		}
	}
}
</style>

上面为组件的简单封装,然后在需要的地方引入组件调用就可以了

效果

发布了29 篇原创文章 · 获赞 4 · 访问量 3598

猜你喜欢

转载自blog.csdn.net/qq_37564189/article/details/103829722
今日推荐