<script setup> import { reactive, ref, onMounted, onUnmounted, nextTick } from 'vue'; const dragData = reactive({ beginClientX: 0, /*距离屏幕左端距离*/ mouseMoveStata: false, /*触发拖动状态 判断*/ maxwidth: '', /*拖动最大宽度,依据滑块宽度算出来的*/ confirmSuccess: false /*验证成功判断*/, message: '请按住滑块,拖动到最右边', }) const dragDivRef = ref(null) const moveDivRef = ref(null) /** * 拖动验证部分 */ const initBar = () => { nextTick(() => { // 根据滑块宽度计算可拖动最大宽度 dragData.maxwidth = dragDivRef.value.clientWidth - moveDivRef.value.clientWidth; // 监听手指的触摸事件 document.addEventListener('mousemove', mouseMoveFn); // 监听手指离开事件 document.addEventListener('mouseup', moseUpFn) }) } const mousedownFn = (e) => { if (!dragData.confirmSuccess) { e.preventDefault && e.preventDefault(); //阻止文字选中等 浏览器默认事件 dragData.mouseMoveStata = true; dragData.beginClientX = e.clientX; } } const mouseMoveFn = (e) => { if (dragData.mouseMoveStata) { let width = e.clientX - dragData.beginClientX; if (width > 0 && width <= dragData.maxwidth) { document.getElementsByClassName('moveDivBar')[0].style.left = width + 'px'; document.getElementById('moveBgInfo').style.width = width + 'px'; } else if (width > dragData.maxwidth) { document.getElementsByClassName('moveDivBar')[0].style.left = dragData.maxwidth + 'px'; document.getElementById('moveBgInfo').style.width = dragData.maxwidth + 'px'; dragData.mouseMoveStata = false dragData.confirmSuccess = true dragData.message = '验证通过' } } } const moseUpFn = (e) => { dragData.mouseMoveStata = false; if (!dragData.confirmSuccess) { var width = e.clientX - dragData.beginClientX; if (width < dragData.maxwidth) { document.getElementsByClassName('moveDivBar')[0].style.left = 0 + 'px'; document.getElementById('moveBgInfo').style.width = 0 + 'px'; dragData.confirmSuccess = false } } }; onMounted(() => { initBar() }) onUnmounted(() => { // 销毁监听移动 document.removeEventListener('mousemove', mouseMoveFn); // 销毁监听手指离开事件 document.removeEventListener('mouseup', moseUpFn) }) /** * 拖动验证部分 */ </script> <template> <div style="width: 400px;height: 38px; border: 1px solid #CED4DA;border-radius: 0.25rem; position: relative; text-align: center; line-height: 38px;user-select: none;" ref="dragDivRef"> <div @mousedown="mousedownFn($event)" class="moveDivBar d-flex align-items-center justify-content-center" style="height: 36px; background-color: #cfd4d9; width: 62px; position: absolute;left:0; cursor: move; border-radius:0 0.19rem 0.19rem 0 ;z-index: 2;" ref="moveDivRef"> <i style="font-size: 20px;" class="ri-arrow-right-s-line"></i> <i style="font-size: 20px; margin-left: -10px;" class="ri-arrow-right-s-line"></i> </div> <div v-if="!dragData.mouseMoveStata" style="color: #888a98;position: absolute;text-align: center;margin: 0 auto; width: 100%; z-index: 1;"> {{ dragData.message }}</div> <div v-if="dragData.mouseMoveStata" style="color: white;position: absolute;text-align: center;margin: 0 auto; width: 100%; z-index: 1;"> {{ dragData.message }}</div> <div v-if="dragData.confirmSuccess" style="color: white;position: absolute;text-align: center;margin: 0 auto; width: 100%; z-index: 1;"> {{ dragData.message }}</div> <div id="moveBgInfo" style="position: absolute; background-color: #51b09d;height: 36px; left: 0; top: 0;border-radius:0.19rem 0 0 0.19rem"> </div> </div> </template>
图标需要自行替换
今ならできます。