You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							291 lines
						
					
					
						
							6.9 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							291 lines
						
					
					
						
							6.9 KiB
						
					
					
				
								<template>
							 | 
						|
									<view class="swipe_action_box" @touchstart="onTouchstart" @touchmove="onTouchmove" @touchcancel="onTouchcancel" @touchend="onTouchend">
							 | 
						|
										<view class="swipe_action_item" :style="{ width: (screenWidth + maxWidth) + 'px', transform: 'translateX(' + translateX + 'px)', transition: 'transform ' + animationTime + 'ms cubic-bezier(.165, .84, .44, 1)'  }">
							 | 
						|
											<view class="swipe_action_content"><slot></slot></view>
							 | 
						|
											<view class="swipe_action_btn_box" ref="swipeActionBtnBox" :class="{'mune-show': mune_show}">
							 | 
						|
												<view v-for="(item,index) of options" :key="index" class="swipe_action_btn" :style="{
							 | 
						|
												  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD'
							 | 
						|
												}" @click.stop="onBtn(index,item)">
							 | 
						|
													<text :style="{
							 | 
						|
													  fontSize: item.style && item.style.fontSize ? item.style.fontSize : '14px',
							 | 
						|
													  color: item.style && item.style.color ? item.style.color : '#FFFFFF'
							 | 
						|
													}">{{ item.text }}</text>
							 | 
						|
												</view>
							 | 
						|
											</view>
							 | 
						|
										</view>
							 | 
						|
									</view>
							 | 
						|
								</template>
							 | 
						|
								
							 | 
						|
								<script>
							 | 
						|
								// https://ext.dcloud.net.cn/plugin?id=2177
							 | 
						|
								// #ifdef APP-NVUE
							 | 
						|
								const dom = weex.requireModule('dom');
							 | 
						|
								// #endif
							 | 
						|
								export default {
							 | 
						|
									props: {
							 | 
						|
										/**
							 | 
						|
										 * 按钮内容
							 | 
						|
										 */
							 | 
						|
										options: {
							 | 
						|
											type: Array,
							 | 
						|
											default () {
							 | 
						|
												return []
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										/**
							 | 
						|
										 * 禁用
							 | 
						|
										 */
							 | 
						|
										disabled: {
							 | 
						|
											type: Boolean,
							 | 
						|
											default: false
							 | 
						|
										},
							 | 
						|
										/**
							 | 
						|
										 * 变量控制开关
							 | 
						|
										 */
							 | 
						|
										show: {
							 | 
						|
											type: Boolean,
							 | 
						|
											default: false
							 | 
						|
										},
							 | 
						|
										/**
							 | 
						|
										 * 是否自动关闭
							 | 
						|
										 */
							 | 
						|
										autoClose: {
							 | 
						|
											type: Boolean,
							 | 
						|
											default: true
							 | 
						|
										},
							 | 
						|
										/**
							 | 
						|
										 * swipe-action 的索引值
							 | 
						|
										 */
							 | 
						|
										index: {
							 | 
						|
											type: Number,
							 | 
						|
											default: 0
							 | 
						|
										}
							 | 
						|
									},
							 | 
						|
									data() {
							 | 
						|
										return {
							 | 
						|
											//开始触摸时间
							 | 
						|
											startTime: 0,
							 | 
						|
											//开始触摸距离
							 | 
						|
											touchStartX: 0,
							 | 
						|
											//最大距离
							 | 
						|
											maxWidth: 58,
							 | 
						|
											//滑动距离
							 | 
						|
											translateX: 0,
							 | 
						|
											animationTime: 0,
							 | 
						|
											//上次的位置
							 | 
						|
											currentX: 0,
							 | 
						|
											screenWidth: 0,
							 | 
						|
											mune_show: false
							 | 
						|
										};
							 | 
						|
									},
							 | 
						|
									watch:{
							 | 
						|
										show(val){
							 | 
						|
											if(val){
							 | 
						|
												this.animationTime = 350;
							 | 
						|
												this.translateX = -this.maxWidth;
							 | 
						|
											}else {
							 | 
						|
												this.animationTime = 350;
							 | 
						|
												this.translateX = 0;
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										translateX(val){
							 | 
						|
											if(val == 0){
							 | 
						|
												this.mune_show = false;
							 | 
						|
											}else{
							 | 
						|
												this.mune_show = true;
							 | 
						|
											}
							 | 
						|
										}
							 | 
						|
									},
							 | 
						|
									created() {
							 | 
						|
										let systemInfo = uni.getSystemInfoSync();
							 | 
						|
										this.screenWidth = systemInfo.screenWidth;
							 | 
						|
									},
							 | 
						|
									mounted() {
							 | 
						|
										const _this = this;
							 | 
						|
										setTimeout(() => {
							 | 
						|
											// #ifdef APP-NVUE
							 | 
						|
											dom.getComponentRect(this.$refs['swipeActionBtnBox'], (data) => {
							 | 
						|
												_this.maxWidth = data.size.width;
							 | 
						|
												if(_this.show){
							 | 
						|
													_this.animationTime = 350;
							 | 
						|
													_this.translateX = -data.size.width;
							 | 
						|
												}
							 | 
						|
											});
							 | 
						|
											// #endif
							 | 
						|
											// #ifndef APP-NVUE
							 | 
						|
											uni.createSelectorQuery().in(this).selectAll('.swipe_action_btn_box')
							 | 
						|
												.boundingClientRect(data => {
							 | 
						|
													_this.maxWidth = data[0].width;
							 | 
						|
													if(_this.show){
							 | 
						|
														_this.animationTime = 350;
							 | 
						|
														_this.translateX = -data[0].width;
							 | 
						|
													}
							 | 
						|
												}).exec()
							 | 
						|
											// #endif
							 | 
						|
										},500);
							 | 
						|
									},
							 | 
						|
									//方法
							 | 
						|
									methods: {
							 | 
						|
										onBtn(index, item) {
							 | 
						|
											this.$emit('button', {
							 | 
						|
												content: item,
							 | 
						|
												index: this.index,
							 | 
						|
												buttonIndex: index
							 | 
						|
											});
							 | 
						|
											if(this.autoClose){
							 | 
						|
												this.animationTime = 350;
							 | 
						|
												this.translateX = 0;
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										// 手指触摸动作开始
							 | 
						|
										onTouchstart(e) {
							 | 
						|
											if(this.disabled){
							 | 
						|
												return;
							 | 
						|
											}
							 | 
						|
											//储存手指触摸坐标,当前时间戳,当前坐标
							 | 
						|
											// #ifdef APP-NVUE
							 | 
						|
											this.touchStartX = e.changedTouches[0].screenX;
							 | 
						|
											// #endif
							 | 
						|
											// #ifndef APP-NVUE
							 | 
						|
											this.touchStartX = e.changedTouches[0].clientX;
							 | 
						|
											// #endif
							 | 
						|
											this.startTime = new Date().getTime();
							 | 
						|
											this.currentX = this.translateX;
							 | 
						|
										},
							 | 
						|
										// 手指触摸后移动
							 | 
						|
										onTouchmove(e) {
							 | 
						|
											if(this.disabled){
							 | 
						|
												return;
							 | 
						|
											}
							 | 
						|
											//手指当前坐标
							 | 
						|
											// #ifdef APP-NVUE
							 | 
						|
											const clientX = e.changedTouches[0].screenX;
							 | 
						|
											// #endif
							 | 
						|
											// #ifndef APP-NVUE
							 | 
						|
											const clientX = e.changedTouches[0].clientX;
							 | 
						|
											// #endif
							 | 
						|
											//计算滑动距离
							 | 
						|
											const difference = this.touchStartX - clientX;
							 | 
						|
											//判断左滑还是右滑
							 | 
						|
											if (difference > 0) {
							 | 
						|
												//计算当前已滑动距离
							 | 
						|
												const leftDifference = this.currentX - Math.abs(difference);
							 | 
						|
												//判断是否大于滑动的最大宽度
							 | 
						|
												if (this.maxWidth < Math.abs(leftDifference)) {
							 | 
						|
													this.animationTime = 0;
							 | 
						|
													this.translateX = -this.maxWidth;
							 | 
						|
												} else {
							 | 
						|
													this.animationTime = 0;
							 | 
						|
													this.translateX = leftDifference;
							 | 
						|
												}
							 | 
						|
											} else {
							 | 
						|
												const rightDifference = this.currentX + Math.abs(difference);
							 | 
						|
												if (0 < rightDifference) {
							 | 
						|
													this.animationTime = 0;
							 | 
						|
													this.translateX = 0;
							 | 
						|
												} else {
							 | 
						|
													this.animationTime = 0;
							 | 
						|
													this.translateX = rightDifference;
							 | 
						|
												}
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										// 手指触摸动作被打断,如来电提醒,弹窗
							 | 
						|
										onTouchcancel(e) {
							 | 
						|
											if(this.disabled){
							 | 
						|
												return;
							 | 
						|
											}
							 | 
						|
											// #ifdef APP-NVUE
							 | 
						|
											this.finallySlide(e.changedTouches[0].screenX);
							 | 
						|
											// #endif
							 | 
						|
											// #ifndef APP-NVUE
							 | 
						|
											this.finallySlide(e.changedTouches[0].clientX);
							 | 
						|
											// #endif
							 | 
						|
											
							 | 
						|
										},
							 | 
						|
										// 手指触摸动作结束
							 | 
						|
										onTouchend(e) {
							 | 
						|
											if(this.disabled){
							 | 
						|
												return;
							 | 
						|
											}
							 | 
						|
											// #ifdef APP-NVUE
							 | 
						|
											this.finallySlide(e.changedTouches[0].screenX);
							 | 
						|
											// #endif
							 | 
						|
											// #ifndef APP-NVUE
							 | 
						|
											this.finallySlide(e.changedTouches[0].clientX);
							 | 
						|
											// #endif
							 | 
						|
										},
							 | 
						|
										//最终判断滑动
							 | 
						|
										finallySlide(finallyX) {
							 | 
						|
											//手指离开的时间
							 | 
						|
											const endTime = new Date().getTime();
							 | 
						|
											//手机滑动屏幕的总花费时间
							 | 
						|
											const timeDifference = endTime - this.startTime;
							 | 
						|
											//手指触摸总滑动距离
							 | 
						|
											const distanceDifference = this.touchStartX - finallyX;
							 | 
						|
											//判断最终滑动方向
							 | 
						|
											if (distanceDifference > 0) {
							 | 
						|
												//判断是否滑动到左边  滑动距离超过3分之一 或者 滑动时间在300毫秒并且距离在4分之一
							 | 
						|
												if (Math.abs(this.translateX) > this.maxWidth / 2 || (timeDifference < 300 && distanceDifference > this.maxWidth / 4)) {
							 | 
						|
													this.animationTime = 350;
							 | 
						|
													this.translateX = -this.maxWidth;
							 | 
						|
												} else {
							 | 
						|
													this.animationTime = 350;
							 | 
						|
													this.translateX = 0;
							 | 
						|
												}
							 | 
						|
												
							 | 
						|
											} else if (distanceDifference < 0) {
							 | 
						|
												//判断是否滑动到右边  滑动距离超过3分之一 或者 滑动时间在300毫秒并且距离在4分之一
							 | 
						|
												if (Math.abs(this.translateX) < this.maxWidth / 2 || (timeDifference < 300 && Math.abs(distanceDifference) > this.maxWidth / 4)) {
							 | 
						|
													this.animationTime = 350;
							 | 
						|
													this.translateX = 0;
							 | 
						|
												} else {
							 | 
						|
													this.animationTime = 350;
							 | 
						|
													this.translateX = -this.maxWidth;
							 | 
						|
												}
							 | 
						|
											}
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								};
							 | 
						|
								</script>
							 | 
						|
								<style scoped>
							 | 
						|
								.swipe_action_box {
							 | 
						|
									overflow: hidden;
							 | 
						|
									width: 750rpx;
							 | 
						|
								}
							 | 
						|
								.swipe_action_item {
							 | 
						|
									/* #ifndef APP-NVUE */
							 | 
						|
									display: flex;
							 | 
						|
									/* #endif */
							 | 
						|
									flex-direction: row;
							 | 
						|
								}
							 | 
						|
								.swipe_action_content {
							 | 
						|
									/* width: 750rpx; */
							 | 
						|
									width: max-content;
							 | 
						|
									/* #ifndef APP-NVUE */
							 | 
						|
									flex-shrink: 0;
							 | 
						|
									/* #endif */
							 | 
						|
								}
							 | 
						|
								.swipe_action_btn_box {
							 | 
						|
									/* #ifndef APP-NVUE */
							 | 
						|
									display: flex;
							 | 
						|
									flex-shrink: 0;
							 | 
						|
									/* #endif */
							 | 
						|
									flex-direction: row;
							 | 
						|
									visibility: hidden;
							 | 
						|
								}
							 | 
						|
								.mune-show{
							 | 
						|
									visibility: initial;
							 | 
						|
								}
							 | 
						|
								.swipe_action_btn {
							 | 
						|
									/* #ifndef APP-NVUE */
							 | 
						|
									display: flex;
							 | 
						|
									/* #endif */
							 | 
						|
									flex-direction: row;
							 | 
						|
									align-items: center;
							 | 
						|
									justify-content: center;
							 | 
						|
									padding: 0 30rpx;
							 | 
						|
								}
							 | 
						|
								.swipe_action_btn:nth-child(1){
							 | 
						|
									margin-left: 20rpx;
							 | 
						|
								}
							 | 
						|
								</style>
							 |