网上找了找没有VUE3的,就自己写了一个兼容PC和手机端
<template> <div class="sliderverify"> <div @touchstart="touch" @mousedown="touch" :class="statusItem[status]"></div> </div> </template> <script> import { ref, getCurrentInstance } from "vue"; export default { porps: { width: { type: String, default: "100%" } }, emits: ["change"], setup(porps, { emit }) { const { ctx } = getCurrentInstance() console.log(porps) const status = ref(0) const disX = ref(0) const statusItem = ["button", "success"] const touch = (e) => { const clientX = e.clientX || e.changedTouches[0].clientX; const pw = e.target.parentElement.offsetWidth - e.target.offsetWidth e.target.onmousemove = e.target.ontouchmove = (m) => { var x = (m.clientX || m.changedTouches[0].clientX) - clientX disX.value = x < 0 ? 0 : pw <= x ? pw - 2 : x e.target.style.transform = `translateX(${disX.value}px)` e.preventDefault(); } ctx.$root.$el.onmouseup = e.target.ontouchend = () => { ctx.$root.$el.onmouseup = e.target.onmousemove = null status.value = Math.abs(disX.value - pw) < 3 ? 1 : 0 emit("change", status.value) e.target.style.transform = `translateX(${0}px)` } } return { touch, status, statusItem } } } </script> <style scoped> .sliderverify { display: block; height: 30px; background-color: #eee; border: 1px solid #ddd; border-radius: 5px; position: relative; } .sliderverify .button, .sliderverify .success, .sliderverify .fail { position: absolute; display: block; height: 100%; background-color: #fff; width: 40px; border-radius: 5px; } .sliderverify .button::before, .sliderverify .button::after, .sliderverify .success::after { position: absolute; display: block; content: ""; width: 10px; height: 10px; border-left: 2px solid #bbb; border-bottom: 2px solid #bbb; transform: rotate(225deg); margin-left: 15px; margin-top: 8px; } .sliderverify .button::after { margin-left: 8px; margin-top: 8px; } .sliderverify .success::after { width: 14px; height: 8px; transform: rotate( 307deg ); margin: 7px 0 0 11px; } .sliderverify .success { background-color: #67c23a; right: 0; } </style>