当前位置:首页 » 《随便一记》 » 正文

vue3+ts 登陆页面,前端实现滑块验证

28 人参与  2022年11月18日 08:25  分类 : 《随便一记》  评论

点击全文阅读


<template>    <div class="login" @keyup.enter="clickLogin">        <div class="loginModule" ref="formWrap">            <div class="logo">                <img src="@/assets/images/logo.png" alt="" />            </div>            <div class="form">                <el-form ref="loginFormRef" :rules="loginRules" :model="loginForm">                    <el-form-item prop="username">                        <el-input                            clearable                            placeholder="用户名"                            v-model="loginForm.username"                        >                        </el-input>                    </el-form-item>                    <el-form-item prop="password">                        <el-input                            clearable                            show-password                            placeholder="密码"                            v-model="loginForm.password"                        >                        </el-input>                    </el-form-item>                    <div class="sliderValidate">                        <div                            class="validateWrap"                            ref="sliderWrap"                            :class="{                                validatePass: validPass                            }"                        >                            <div class="block" ref="slider">                                <img                                    v-show="validPass"                                    src="@/assets/images/Login/slider-icon.png"                                    alt="滑块"                                />                                <div class="sliderIcon" v-show="!validPass">                                    <DArrowRight style="width: 1em; height: 1em; " />                                </div>                            </div>                            <span v-show="validPass" class="validatePass">验证通过</span>                            <span v-show="!validPass" class="noValidate">拖动滑块校验</span>                        </div>                    </div>                    <div class="showResetPassword">                        <p>                            <span class="sliderValid" v-if="showSliderWarn">请拖动滑块完成校验</span>                        </p>                    </div>                </el-form>                <a-button class="loginButton" type="primary" @click="clickLogin">登录</a-button>            </div>        </div>    </div></template><script lang="ts" setup>// ref:用于声明基础类型响应式数据, reactive:用于声明复杂类型响应式数据。unref:如果参数是一个 ref 则返回它的 value,否则返回参数本身import { reactive, ref, unref, onMounted, inject, getCurrentInstance } from "vue";// 接口import { login } from "@/api/User";// 节流import throttle from "@/utils/common"// 提示信息const Mes: any = inject('$message')// 登陆密码加密import { submitEncrypt } from '@/utils/jsencrypt';// 对用户和密码进行类型限制interface loginData {    username: string;    password: string;}//登录数据let loginForm = reactive<loginData>({    username: "",    password: ""});// 检查用户名是否存在const usernameCheck = async (rule: any, value: string, cb: any) => {    if (!/^\w{5,20}$/g.test(value)) {        return cb("用户名不合法");    }  };// 登录数据校验let loginRules = reactive({    username: [ { required: true, message: "请输入用户名", trigger: "blur" }, { validator: usernameCheck, trigger: 'blur' } ],    password: [ { required: true, message: "请输入密码", trigger: "blur" } ]});// 表单校验结果const loginFormRef = ref();// 标示滑块校验是否通过const validPass = ref(false)// 显示滑块校验文字提示const showSliderWarn = ref(false)// 滑块 refconst slider = ref()// 滑块容器 refconst sliderWrap = ref()// 登陆模块 refconst formWrap = ref()/** * 为滑块添加事件 */function sliderEvent() {    if (!slider.value || !sliderWrap.value) return null;    // 滑块容器的宽度    const sliderBoxWidth = sliderWrap.value.clientWidth;    // 滑块宽度    const sliderWidth = slider.value.clientWidth;    // 最大可拖动距离    const maxSlideX = sliderBoxWidth - sliderWidth;    // 滑块容器距离屏幕左边的距离(通过父级元素的offsetLeft计算)    const formClientX = formWrap.value.offsetLeft + 43;    // 滑块划过的过程    slider.value.onmousedown = function(e: any) {        const offsetX = e.offsetX        // 滑块校验已通过        if (validPass.value) {            return        }        // 鼠标在页面上进行移动        document.onmousemove = function(e: any) {            if (validPass.value) {                document.onmousemove = null;                document.onmouseup = null;                return;            }            const x = e.clientX - formClientX - offsetX;            if (x > 0 && x < maxSlideX) {                slider.value.style.left = x + "px";            }            if (x < 0) {                slider.value.style.left = "0px";            }            if (x > maxSlideX) {                slider.value.style.left = maxSlideX + "px";                validPass.value = true;                showSliderWarn.value = false;            }            if (x === maxSlideX) {                validPass.value = true;                showSliderWarn.value = false;            }        }        //鼠标按键被松开        document.onmouseup = function(e: any) {            const centerX = sliderBoxWidth / 2 - 23;            let x = e.clientX - formClientX - offsetX;                        let timer: any = null;                        // 恢复到起始点            if (x <= centerX && x > 0) {                timer = setInterval(() => {                    x -= 2;                    if (x <= 0) {                        clearInterval(timer);                        slider.value.style.left = "0px";                    }                                        slider.value.style.left = x + "px";                }, 1);            } else if (x > centerX && x < maxSlideX) { // 终点                timer = setInterval(() => {                    x += 2;                    if (x >= maxSlideX) {                        clearInterval(timer);                        slider.value.style.left = maxSlideX + "px";                        validPass.value = true;                        showSliderWarn.value = false;                    }                    slider.value.style.left = x + "px";                }, 1);            }            document.onmousemove = null;            document.onmouseup = null;        }    }}// 节流const throttles = throttle(2000);/** * 登陆 */const clickLogin = () => {    throttles(async () => {        const form: any = unref(loginFormRef)        await form.validate()        if (validPass.value) {            showSliderWarn.value = false;            // 登陆            await isLogin();        } else {            showSliderWarn.value = true;        }    })}/** * 执行登陆 */async function isLogin() {    try {        const { data } = await login({            username: loginForm.username,            password: submitEncrypt(loginForm.password)        })        if (data.code) {        //登陆成功        }else{        // 失败        }               } catch (err) {        console.log('e', err)        Mes.error('用户名或密码错误,请重试')    }}onMounted(() => {    // ref页面组件还没有挂载完成,需要在挂载完成之后才能使用refs    sliderEvent()});</script><style lang="scss" scoped src="./Login.scss"></style>

点击全文阅读


本文链接:http://zhangshiyu.com/post/48877.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1