<!-- -->
<template>
<div ref="wrap" class="slider-unlock">
<div class="before">请按住滑块,拖动到最右边</div>
<div ref="after" class="after">
<div class="after-inner">{{ success ? '验证成功' : '请按住滑块,拖动到最右边' }}</div>
</div>
<div ref="slider" class="slider">
<i class="iconfont icon-a-" v-if="!success"></i>
<i class="iconfont icon-dagou" v-else></i>
</div>
</div>
</template>
<script setup lang="ts">
const success = ref(false)
var clear: any = null
const after: any = ref(null)
const slider: any = ref(null)
const wrap: any = ref(null)
const emit = defineEmits(["sliderNo"]);
function init() {
// 设置after-inner的固定宽度
after.value.childNodes[0].style.width = wrap.value.offsetWidth + 'px'
// 滑块移动最大位置
const limit = wrap.value.offsetWidth - slider.value.offsetWidth
// 实时计算滑块的偏移量
let offsetX: any
// 点击滑块时的鼠标X位置
let initX: any
// // 页面鼠标移动事件
const docMousemoveHandler = (e: any) => {
// 获取移动后鼠标实时位置
const moveX = e.clientX
// 计算滑块应该移动的偏移量
offsetX = moveX - initX
// 限制上下限
if (offsetX < 0) {
offsetX = 0
} else if (offsetX > limit) {
offsetX = limit
}
// 移动滑块
slider.value.style.left = offsetX + 'px'
// 修改高亮背景宽度
after.value.style.width = offsetX + 'px'
//此处写你要做函数
if (offsetX >= limit) {
success.value = true
emit('sliderNo', false)
document.removeEventListener('mousemove', docMousemoveHandler)
slider.value.removeEventListener('mousedown', sliderMousedownHandler)
}
}
// 页面鼠标松开事件
const docMouseupHandler = (e: any) => {
// 解绑事件
document.removeEventListener('mousemove', docMousemoveHandler)
// 重置滑块
if (offsetX < limit) {
slider.value.style.left = 0
after.value.style.width = 0
}
}
// 滑块点击事件
const sliderMousedownHandler = (e: any) => {
// 获取鼠标位置
initX = e.clientX
// 绑定页面的鼠标移动事件
document.addEventListener('mousemove', docMousemoveHandler)
}
// 绑定滑块点击事件
slider.value.addEventListener('mousedown', sliderMousedownHandler)
// 页面鼠标松开事件
document.addEventListener('mouseup', docMouseupHandler)
// 定义清理方法
clear = () => {
document.removeEventListener('mousemove', docMousemoveHandler)
slider.value.removeEventListener('mousedown', sliderMousedownHandler)
document.removeEventListener('mouseup', docMouseupHandler)
}
}
onMounted(() => {
init()
})
onBeforeUnmount(() => {
clear && clear()
})
</script>
<style lang='scss' scoped>
.slider-unlock {
width: 238px;
height: 36px;
background: #DDE1ED;
border-radius: 4px;
position: relative;
overflow: hidden;
border: 1px solid #CCCCCC;
box-sizing: border-box;
user-select: none;
.before,
.after {
position: absolute;
margin: -1px 0 0 -1px;
top: 0;
left: 0;
z-index: 1;
height: 100%;
box-sizing: content-box;
font-size: 14px;
line-height: 36px;
text-indent: 4em;
}
.before {
width: 100%;
color: #92979C;
padding: 0 1px 1px 0;
}
.after {
width: 0;
overflow: hidden;
padding: 0 0 1px 0;
&-inner {
position: absolute;
width: 100%;
height: 100%;
color: #fff;
background-color: #40C057;
}
}
.slider {
position: absolute;
margin: -1px 0 0 -1px;
top: 0;
left: 0;
z-index: 3;
width: 48px;
height: 36px;
line-height: 36px;
text-align: center;
border: 1px solid #CCC;
cursor: pointer;
background: no-repeat center center #fff;
.icon-a- {
color: rgb(146, 151, 156);
}
.icon-dagou {
color: rgb(0, 202, 200);
}
}
}
</style>
直接封装一个组件 即开即用
如果觉得好用 点赞一下 谢谢~