180 lines
3.9 KiB
Vue
180 lines
3.9 KiB
Vue
<template>
|
|
<view class="next-slide" :class="{'next-slide-disabled': disabled}">
|
|
<view class="next-slide-left" :style="'position: relative;left:'+left+'rpx'" @touchstart="ontouchstart"
|
|
@touchmove="ontouchmove" @touchend="ontouchend">
|
|
<slot></slot>
|
|
</view>
|
|
<view class="next-slide-right">
|
|
<view
|
|
class="next-btn-item"
|
|
v-for="(item,index) in btnGroup"
|
|
:key="index"
|
|
:style="getStyle(item)"
|
|
@click.stop="btnClick(item)">
|
|
{{item.name}}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
const defBtnStyle = {
|
|
width: '100rpx',
|
|
bgColor: '#f9ae3d',
|
|
color: '#FFFFFF',
|
|
fontSize: '28rpx',
|
|
fontWeight: 300
|
|
};
|
|
|
|
export default {
|
|
name: 'NextSwipeAction',
|
|
props: {
|
|
btnGroup: {
|
|
type: Array,
|
|
default: () => {
|
|
return [{
|
|
name: '修改',
|
|
style: {
|
|
bgColor: '#f9ae3d'
|
|
}
|
|
}, {
|
|
name: '删除',
|
|
style: {
|
|
bgColor: '#ff4d4f'
|
|
}
|
|
}]
|
|
}
|
|
},
|
|
//当前列索引
|
|
index: {
|
|
type: Number,
|
|
require: true,
|
|
default: 0
|
|
},
|
|
//是否禁用
|
|
disabled: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
// 是否按钮点击后自定重置
|
|
btnClickAutoReset: {
|
|
type: Boolean,
|
|
default: true
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
x: 0,
|
|
left: 0,
|
|
operation: 0,
|
|
height: 0,
|
|
screenWidth: 0
|
|
};
|
|
},
|
|
mounted() {
|
|
this.$nextTick(res => {
|
|
const systemInfo = uni.getSystemInfoSync()
|
|
this.screenWidth = systemInfo.screenWidth
|
|
this.getBtnWidth()
|
|
this.getListHeight()
|
|
})
|
|
},
|
|
methods: {
|
|
getStyle(item) {
|
|
const style = item.style || {};
|
|
const styleStr = 'width:'+ (style.width || defBtnStyle.width) +
|
|
';height:100%;background-color:' + (style.bgColor || defBtnStyle.bgColor) +
|
|
';color:' + (style.color || defBtnStyle.color) +
|
|
';font-size:' + (style.fontSize || defBtnStyle.fontSize) +
|
|
'font-weight:' + (style.fontWeight || defBtnStyle.fontWeight);
|
|
return styleStr
|
|
},
|
|
btnClick(item) {
|
|
const it = Object.assign({}, item);
|
|
delete it.style;
|
|
this.$emit('btnClick', {
|
|
index: this.index,
|
|
item: it
|
|
})
|
|
if(this.btnClickAutoReset) {
|
|
this.reset()
|
|
}
|
|
},
|
|
//重置方法
|
|
reset() {
|
|
this.left = 0
|
|
},
|
|
getBtnWidth() {
|
|
const element = uni.createSelectorQuery().in(this).select(".next-slide-right");
|
|
element.boundingClientRect(rect => {
|
|
this.operation = this.px2rpx(rect.width, this.screenWidth)
|
|
}).exec()
|
|
},
|
|
getListHeight() {
|
|
const element = uni.createSelectorQuery().in(this).select(".next-slide-left");
|
|
element.boundingClientRect(rect => {
|
|
console.log(rect)
|
|
this.height = this.px2rpx(rect.height, this.screenWidth)
|
|
}).exec()
|
|
},
|
|
px2rpx(px, screenWidth) {
|
|
return px / (screenWidth / 750)
|
|
},
|
|
ontouchstart(e) {
|
|
if(this.disabled) return
|
|
this.x = this.px2rpx(e.touches[0].clientX, this.screenWidth)
|
|
},
|
|
ontouchmove(e) {
|
|
if(this.disabled) return
|
|
let clientX = this.x - this.px2rpx(e.touches[0].clientX, this.screenWidth)
|
|
if (clientX <= 0) this.left = 0
|
|
else if (this.operation <= clientX) this.left = this.operation * -1
|
|
else this.left = clientX * -1
|
|
},
|
|
ontouchend(e) {
|
|
if(this.disabled) return
|
|
let clientX = this.x - this.px2rpx(e.changedTouches[0].clientX, this.screenWidth)
|
|
this.left = clientX > this.operation / 2 ? this.operation * -1 : 0
|
|
},
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.next-slide {
|
|
width: 100%;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
.next-slide-disabled {
|
|
background-color: #333333;
|
|
opacity: 0.6;
|
|
}
|
|
.next-slide-left {
|
|
width: 100%;
|
|
overflow: hidden;
|
|
background-color: #FFFFFF;
|
|
transition: left 0.2s ease-in-out;
|
|
z-index: 999;
|
|
}
|
|
|
|
.next-slide-right {
|
|
position: absolute;
|
|
top: 0rpx;
|
|
right: 0;
|
|
z-index: 99;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
height: 14.5vw;
|
|
}
|
|
|
|
.next-btn-item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 5vw;
|
|
padding: 1vw;
|
|
height: 100%;
|
|
}
|
|
</style> |