|
|
<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>// #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>
|