swipe-action
swipe-action滑动菜单
组件结构
<template>
<view class="tui-swipeout-wrap">
<view class="tui-swipeout-item" :class="[isShowBtn?'swipe-action-show':'']" @touchstart="handlerTouchstart"
@touchmove="handlerTouchmove" @touchend="handlerTouchend" :style="{transform:'translate(' + position.pageX + 'px,0);'}">
<view class="tui-swipeout-content">
<slot name="content"></slot>
</view>
<view class="tui-swipeout-button-right-group" v-if="actions.length > 0" @touchend.stop="loop">
<view class="tui-swipeout-button-right-item" v-for="(item,index) in actions" :key="index" :style="{background:item.background || '#f7f7f7',color:item.color,width:item.width+'px'}"
:data-index="index" @tap="handlerButton">
<image :src="item.icon" v-if="item.icon" :style="{width:px(item.imgWidth),height:px(item.imgHeight)}"></image>
<text :style="{fontSize:px(item.fontsize)}">{{item.name}}</text>
</view>
</view>
<!--actions长度设置为0,可直接传按钮进来-->
<view class="tui-swipeout-button-right-group" @touchend.stop="loop" @tap="handlerParentButton" v-if="actions.length === 0"
:style="{width:operateWidth+'px',right:'-'+operateWidth+'px'}">
<slot name="button"></slot>
</view>
</view>
<view v-if="isShowBtn && showMask" class="swipe-action_mask" @tap="closeButtonGroup" @touchmove.stop="closeButtonGroup" />
</view>
</template>
组件脚本
<script>
export default {
name: "tuiSwipeAction",
props: {
// name: '删除',
// color: '#fff',
// fontsize: 32,//单位upx
// width: 80, //单位px
// icon: 'like.png',//此处为图片地址
// background: '#ed3f14'
actions: {
type: Array,
default: []
},
//是否可关闭,默认可关闭,可以单独控制
closable: {
type: Boolean,
default: true
},
//设为false,可以滑动多行不关闭菜单
showMask: {
type: Boolean,
default: true
},
operateWidth: {
type: Number,
default: 80
},
params: {
type: Object,
default: {}
}
},
watch: {
actions(newValue, oldValue) {
this.updateButtonSize()
}
},
data() {
return {
//start position
tStart: {
pageX: 0,
pageY: 0
},
//限制滑动距离
limitMove: 0,
//move position
position: {
pageX: 0,
pageY: 0
},
isShowBtn: false
};
},
// #ifdef H5
mounted() {
this.updateButtonSize()
},
// #endif
onReady() {
this.updateButtonSize()
},
methods: {
swipeDirection(x1, x2, y1, y2) {
return Math.abs(x1 - x2) >=
Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
},
//阻止事件冒泡
loop() {},
updateButtonSize() {
const actions = this.actions;
if (actions.length > 0) {
const query = uni.createSelectorQuery().in(this);
let limitMovePosition = 0;
actions.forEach(item => {
limitMovePosition += item.width || 0;
});
this.limitMove = limitMovePosition;
} else {
this.limitMove = this.operateWidth;
}
},
handlerTouchstart(event) {
const touches = event.touches ? event.touches[0] : {};
const tStart = this.tStart;
if (touches) {
for (let i in tStart) {
if (touches[i]) {
tStart[i] = touches[i];
}
}
}
},
swipper(touches) {
const start = this.tStart;
const spacing = {
pageX: touches.pageX - start.pageX,
pageY: touches.pageY - start.pageY
}
if (this.limitMove < Math.abs(spacing.pageX)) {
spacing.pageX = -this.limitMove;
}
this.position = spacing
},
handlerTouchmove(event) {
const start = this.tStart;
const touches = event.touches ? event.touches[0] : {};
if (touches) {
const direction = this.swipeDirection(start.pageX, touches.pageX, start.pageY, touches.pageY);
if (direction === 'Left') {
this.swipper(touches);
}
}
},
handlerTouchend(event) {
const start = this.tStart;
const touches = event.changedTouches ? event.changedTouches[0] : {};
if (touches) {
const direction = this.swipeDirection(start.pageX, touches.pageX, start.pageY, touches.pageY);
const spacing = {
pageX: touches.pageX - start.pageX,
pageY: touches.pageY - start.pageY
}
if (Math.abs(spacing.pageX) >= 40 && direction === "Left") {
spacing.pageX = spacing.pageX < 0 ? -this.limitMove : this.limitMove;
this.isShowBtn = true
} else {
spacing.pageX = 0;
}
this.position = spacing
}
},
handlerButton(event) {
if (this.closable) {
this.closeButtonGroup();
}
const dataset = event.currentTarget.dataset;
this.$emit('click', {
index: Number(dataset.index),
item: this.params
})
},
closeButtonGroup() {
this.position = {
pageX: 0,
pageY: 0
};
this.isShowBtn = false
},
//控制自定义组件
handlerParentButton(event) {
if (this.closable) {
this.closeButtonGroup();
}
},
px(num) {
return uni.upx2px(num) + "px"
}
}
}
</script>
组件样式
... 此处省略n行
脚本说明
props:
"actions" : 按钮信息,类型:"Array",默认值:[],数组内容:
[
name: '删除',
color: '#fff',
fontsize: 32,//单位upx
width: 80, //单位px
icon: 'like.png',//此处为图片地址
background: '#ed3f14'
]
"closable" : 是否可关闭,默认可关闭,可以单独控制,类型:"Boolean",默认值:true
"showMask" : 是否显示遮罩, 设为false,可以滑动多行不关闭菜单,类型:"Boolean",默认值:true
"operateWidth" : 按钮宽度,类型:"Number",默认值:80px
"params" : 参数,类型:"Object",默认值:{}
methods:
"handlerButton":按钮点击事件
"closeButtonGroup":关闭滑动
示例
... 此处省略n行,下载源码查看