此组件基于 Vant ActionSheet 进行二次开发,增加可以手势滑动关闭的功能。 slot 动态渲染
<template>
<div class="action-sheet">
<van-action-sheet
v-bind="$attrs"
:style="{ bottom: `-${translateY}px` }"
@click-overlay="handleClickOverlay"
>
<div
class="grabber icon icon-grabber"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>
</div>
<slot v-for="(_, name) in $slots" :name="name"></slot>
</van-action-sheet>
</div>
</template>
<script>
export default {
data() {
return {
startY: 0,
moveY: 0,
translateY: 0,
threshold: 50
};
},
watch: {
'$attrs.value': {
immediate: true, // 立即执行
handler(val) {
if (val) {
this.translateY = 0;
}
}
}
},
methods: {
handleTouchStart(event) {
this.startY = event.touches[0].clientY;
},
handleTouchMove(event) {
this.moveY = event.touches[0].clientY;
// 计算滑动距离并更新 ActionSheet 的位置
const distance = this.moveY - this.startY;
if (distance > 0) {
this.translateY = distance;
}
},
handleTouchEnd() {
const distance = this.moveY - this.startY;
if (distance > this.threshold) {
this.$emit('close');
}
else {
// 如果滑动距离不够,则恢复原位
this.translateY = 0;
}
},
handleClickOverlay() {
this.$emit('close');
}
}
};
</script>
<style lang="less" scoped>
.action-sheet {
.grabber {
font-size: 6px;
text-align: center;
padding-top: 6px;
padding-bottom: 10px;
color: var(--color-content-17);
}
}
</style>