uniapp 小程序封装左滑效果组件

uniapp 小程序封装左滑效果组件

引言

小程序电商项目购物车,往往都会有左滑删除功能,在不想使用插件的前提下,就需要自己编写,因此我个人写了一个左滑效果组件

封装组件

//  SlideOperation/index.vue

<template>
	<view class="slide-wrapper" :style="{ transform: activeIndex === index ? 'translateX(' + itemTransLateX + 'rpx)' : 0 }">
		<view class="slide-content" @touchstart="touchStart($event, index)" @touchmove="touchMove($event, index)" @touchend="touchEnd($event, index)">
			<slot></slot>
		</view>
		<view class="operate-btn">
			<view v-if="isDelete" class="delete-btn" @click="delBtn">删除</view>
		</view>
	</view>
</template>

<script>
export default {
    
    
	props: {
    
    
		// 是否滑动
		isSlide: {
    
    
			type: Boolean,
			required: true
		},
		// 每个需要滑动区域的唯一值
		index: {
    
    
			type: Number,
			required: true
		},
		// 是否删除
		isDelete: {
    
    
			type: Boolean,
			required: true
		}
	},
	data() {
    
    
		return {
    
    
			// 当前滑动的区域
			activeIndex: 0,
			// 一开始水平方向的位置
			startX: 0,
			// 滑动的距离
			itemTransLateX: 0
		};
	},
	methods: {
    
    
		touchStart(e, index) {
    
    
			if (!this.isSlide) return;
			this.activeIndex = index;
			this.startX = e.changedTouches[0].clientX;
		},
		touchMove(e, index) {
    
    
			if (!this.isSlide) return;
			let moveX = e.changedTouches[0].clientX;
			this.itemTransLateX = moveX - this.startX >= 0 ? 0 : moveX - this.startX;
		},
		touchEnd(e, index) {
    
    
			if (!this.isSlide) return;
			let endX = e.changedTouches[0].clientX;
			if (endX === this.startX) {
    
    
				return (this.itemTransLateX = 0);
			}
			this.itemTransLateX = endX - this.startX;
			this.itemTransLateX = this.itemTransLateX <= -40 ? -100 : 0;
		},
		delBtn() {
    
    
			this.$emit('deleteProd', this.index);
		}
	},
	watch: {
    
    
		isSlide(newVal, oldVal) {
    
    
			if (!newVal) this.itemTransLateX = 0;
		}
	}
};
</script>

<style lang="scss" scoped>
.slide-wrapper {
    
    
	position: relative;
	display: flex;
	width: 100%;
	transition: all 0.4s;

	.slide-content {
    
    
		display: flex;
		justify-content: space-between;
		align-items: center;
		width: 100%;
		padding-right: 10rpx;
	}

	.operate-btn {
    
    
		position: absolute;
		top: 0;
		right: 0;
		display: flex;
		height: 100%;
		transform: translateX(100%);

		.delete-btn {
    
    
			display: flex;
			justify-content: center;
			align-items: center;
			width: 100rpx;
			height: 100%;
			color: $color-fff;
			font-size: 22rpx;
			background: #f52c2c;
			box-sizing: border-box;
		}
	}
}
</style>

页面使用

<template>
	// ....  
	<slide-operation :isSlide="true" :isDelete="true" :index="index" class="w100" @deleteProd="deleteProd">
		// 此处填写需要进行滑动的内容
	</slide-operation>
	// ..... 
	
// 只复制了具体组件的使用方法,该组件的外部是一个由 v-for 循环生成的标签,因此 index 的值需写成数据内部的唯一值,不可使用 v-for 的index值
</template>
<script>
import SlideOperation from '@/components/SlideOperation/index.vue';
export default {
    
    
	components: {
    
     SlideOperation }
};
</script>

注意事项

由于 ios 手机默认页面可以下滑的情况,加入使用了左滑效果的组件,需要在此上下可以滑动的区域添加 catchtouchmove=“return” 以此来阻止左滑时,页面上下滑动跟着进行的问题

不管是不是当前页面,只要项目出现以下图片这种情况,动画效果将会出现延迟
不管是不是当前页面,只要项目出现这种情况,动画效果将会出现延迟

例如 :滑动区域是 scroll-view ,需要在这个标签添加 catchtouchmove=“return” ,同理,如果是 view 标签,则需要在最顶部控制的 view 添加 catchtouchmove=“return”

此方法是通过网上资料查找和我对项目自身的情况进行封装改造的,如有错误,欢迎各位指出

猜你喜欢

转载自blog.csdn.net/m0_64344940/article/details/127243275