<template>
|
<view>
|
<view class="skidway" id="skidway"
|
:style="{
|
borderRadius: round.show ? round.style : '',
|
height: height + 'rpx',
|
border: border.show ? border.style : ''}">
|
<view :style="{ width:moveWidth + sliderWidth + 'px', borderRadius: round.show ? round.style : '' }" class="end-status skidway-style">
|
<slot name="isFinished">
|
<view style="height: 100%;background-color: #65B58A; color: #fff; display: flex; justify-content: center;align-items: center;">
|
滑动成功
|
</view>
|
</slot>
|
</view>
|
<view class="skidway-style" :style="{borderRadius: round.show ? round.style : ''}">
|
<slot name="init">
|
<view style="background-color: #DEE1E6; color: #000; height: 100%; display: flex; justify-content: center;align-items: center;">右滑解锁</view>
|
</slot>
|
</view>
|
<view
|
:style="{
|
left:moveWidth +'px',
|
borderRadius: round.show ? round.style : '',
|
width: sliderSize + 'rpx',
|
height: sliderSize + 'rpx'}"
|
@touchstart="slideStart"
|
@touchmove="slideMove"
|
@touchend="slideEnd"
|
id="slider"
|
class="slider">
|
<view v-if="!finishFlag" style="height: 100%; width: 100%;">
|
<slot name="begin">
|
<view style="background-color: #E5673B; height: 100%; display: flex; justify-content: center; align-items: center; color: #fff;">
|
开始
|
</view>
|
</slot>
|
</view>
|
<view v-else style="height: 100%; width: 100%;" v-show="isShowEnd">
|
<slot name="end">
|
<view style="background-color: #1BA035; height: 100%; display: flex; justify-content: center; align-items: center; color: #fff;">
|
结束
|
</view>
|
</slot>
|
</view>
|
</view>
|
</view>
|
</view>
|
</template>
|
|
<script>
|
export default {
|
props: {
|
height: {
|
type: Number,
|
default: 80,
|
},
|
sliderSize: {
|
type: Number,
|
default: 80
|
},
|
round: {
|
type: Object,
|
default: function () {
|
return { show: false, style: '1rpx solid #C8C9CC' }
|
}
|
},
|
border: {
|
type: Object,
|
default: function () {
|
return { show: false, style: '1rpx solid #C8C9CC' }
|
}
|
},
|
isShowEndSlider: {
|
type: Boolean,
|
default: true,
|
},
|
},
|
data() {
|
return {
|
initX: 0, // 触发屏幕时的初始位置
|
moveWidth: 0, // 滑动的距离
|
skidwayWidth: 0, // 滑道长度
|
sliderWidth: 0, // 滑块长度
|
finishFlag: false, // 滑动是否完成
|
isMove:true, // 是否可滑动
|
isShowEnd: this.isShowEndSlider // 是否显示结束滑块
|
}
|
},
|
mounted() {
|
const elemt = uni.createSelectorQuery().in(this)
|
elemt.select('#skidway').boundingClientRect((data) => {
|
this.skidwayWidth = data.width;
|
}).exec()
|
elemt.select('#slider').boundingClientRect((data) => {
|
this.sliderWidth = data.width;
|
}).exec()
|
console.log('触发', this.skidwayWidth, this.sliderWidth);
|
},
|
methods: {
|
slideStart(e) {
|
this.initX = e.touches[0].clientX; // 距离屏幕左侧的距离
|
this.isMove = true; // 允许滑动
|
},
|
slideReset() {
|
this.finishFlag = false;
|
this.moveWidth = 0;
|
},
|
slideFinish() {
|
this.isMove = false;
|
this.finishFlag = true;
|
this.$emit('slideFinish', { status: 'success', resetFunc: this.slideReset });
|
},
|
slideMove(e) {
|
if(!this.isMove) return;
|
if (this.moveWidth >= (this.skidwayWidth - this.sliderWidth)) {
|
this.moveWidth = this.skidwayWidth - this.sliderWidth
|
this.slideFinish()
|
} else {
|
let width = e.touches[0].clientX - this.initX;
|
if (width<=0) { // 如果滑动的位置到初始位置的距离小于0,则回到原位
|
width = 0
|
}
|
this.moveWidth = width;
|
}
|
},
|
slideEnd(e) { // 触摸结束判断滑动是否完成,未完成则回到原位
|
if(!this.finishFlag){
|
this.slideReset();
|
}
|
}
|
},
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.skidway {
|
display: flex;
|
align-items: center;
|
position: relative;
|
.slider {
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
position: relative;
|
overflow: auto;
|
z-index: 2;
|
}
|
.skidway-style {
|
width: 100%;
|
height: 100%;
|
overflow: auto;
|
position: absolute;
|
left: 0;
|
top: 0;
|
}
|
.end-status {
|
z-index: 1;
|
}
|
}
|
</style>
|