<template>
<movable-area class="u-swipe-action" :style="{ backgroundColor: bgColor }">
<movable-view
class="u-swipe-view"
@change="change"
@touchend="touchend"
@touchstart="touchstart"
direction="horizontal"
:disabled="disabled"
:x="moveX"
:style="{
width: movableViewWidth ? movableViewWidth : '100%'
}"
>
<view class="u-swipe-content" @tap.stop="contentClick">
<slot></slot>
</view>
<view
class="u-swipe-del"
v-if="showBtn"
@tap.stop="btnClick(index)"
:style="[btnStyle(item.style)]"
v-for="(item, index) in options"
:key="index"
>
<view class="u-btn-text">{{ item.text }}</view>
</view>
</movable-view>
</movable-area>
</template>
<script>
export default {
name: 'u-swipe-action',
props: {
index: {
type: [Number, String],
default: ''
},
btnWidth: {
type: [String, Number],
default: 90
},
disabled: {
type: Boolean,
default: false
},
show: {
type: Boolean,
default: false
},
bgColor: {
type: String,
default: '#ffffff'
},
vibrateShort: {
type: Boolean,
default: false
},
options: {
type: Array,
default() {
return []
}
}
},
watch: {
show: {
immediate: true,
handler(nVal, oVal) {
if (nVal) {
this.open()
} else {
this.close()
}
}
}
},
data() {
return {
moveX: 0,
scrollX: 0,
status: false,
movableAreaWidth: 0,
elId: this.$u.guid(),
showBtn: false
}
},
computed: {
movableViewWidth() {
return this.movableAreaWidth + this.allBtnWidth + 'px'
},
innerBtnWidth() {
return uni.upx2px(this.btnWidth)
},
allBtnWidth() {
return uni.upx2px(this.btnWidth) * this.options.length
},
btnStyle() {
return style => {
let css = {}
style.width = this.btnWidth + 'rpx'
return style
}
}
},
mounted() {
this.$nextTick(() => {
this.getActionRect()
this.showBtn = true
})
},
methods: {
btnClick(index) {
this.status = false
this.$emit('click', this.index, index)
},
change(e) {
this.scrollX = e.detail.x
},
close() {
this.moveX = 0
this.status = false
},
open() {
if (this.disabled) return
this.moveX = -this.allBtnWidth
this.status = true
},
touchend() {
this.moveX = this.scrollX
this.$nextTick(function() {
if (this.status == false) {
if (this.scrollX <= -this.allBtnWidth / 4) {
this.moveX = -this.allBtnWidth
this.status = true
this.emitOpenEvent()
if (this.vibrateShort) uni.vibrateShort()
} else {
this.moveX = 0
this.status = false
this.emitCloseEvent()
}
} else {
if (this.scrollX > (-this.allBtnWidth * 3) / 4) {
this.moveX = 0
this.$nextTick(() => {
this.moveX = 101
})
this.status = false
this.emitCloseEvent()
} else {
this.moveX = -this.allBtnWidth
this.status = true
this.emitOpenEvent()
}
}
})
},
emitOpenEvent() {
this.$emit('open', this.index)
},
emitCloseEvent() {
this.$emit('close', this.index)
},
touchstart() {},
getActionRect() {
this.$uGetRect('.u-swipe-action').then(res => {
this.movableAreaWidth = res.width
})
},
contentClick() {
if (this.status == true) {
this.status = 'close'
this.moveX = 0
}
this.$emit('content-click', this.index)
}
}
}
</script>
<style scoped lang="scss">
@import '../../libs/css/style.components.scss';
.u-swipe-action {
width: auto;
height: initial;
position: relative;
overflow: hidden;
}
.u-swipe-view {
display: flex;
height: initial;
position: relative;
}
.u-swipe-content {
flex: 1;
}
.u-swipe-del {
position: relative;
font-size: 15rpx;
color: #ffffff;
}
.u-btn-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>