Vue3 简单的滑块验证


网上找了找没有VUE3的,就自己写了一个兼容PC和手机端

<template>
    <div class="sliderverify">
        <div class="bg"  :style="`width:${ disX+40 }px;`">div>
        <div ref="btn" :class="statusItem[status]">div>
    div>
template>
<script>

    import { ref, getCurrentInstance, nextTick } from "vue";
    export default {
        porps: {
            width: { type: String, default: "100%" }
        },
        emits: ["change"],
        setup(porps, { emit }) {
            const { ctx} = getCurrentInstance()
            console.log(porps,ctx)
            const status = ref(0)
            const disX = ref(0)
            const statusItem = ["button", "success"]

            nextTick(() => {

                const el = ctx.$refs.btn

                el.onmousedown = el.ontouchstart = (e) => {
                    const clientX = e.clientX || e.changedTouches[0].clientX;
                    const pw = el.parentElement.offsetWidth - el.offsetWidth
                    el.onmousemove = el.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 = el.ontouchend = () => {
                        ctx.$root.$el.onmouseup = el.onmousedown = el.ontouchstart = el.onmousemove = el.ontouchmove = null
                        status.value = Math.abs(disX.value - pw) < 3 ? 1 : 0
                        emit("change", status.value)
                        e.target.style.transform = `translateX(0px)`
                    }
                }

            })
            return { status, statusItem, disX }
        }
    }

script>
<style scoped>
    .sliderverify {
        display: flex ;
        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 .bg {
            position: absolute;
            background-color: #a0cfff;
            border-radius: 5px;
            height: 100%
        }
            .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>
vue