vue+js登陆页面, 前端实现滑块验证

<template>
    <div class="Login" @keyup.enter="clickLogin">
        <div class="innerFormWrap"  ref="formWrap">
            <div class="logo">
               <img src="@/assets/images/logo.png" alt="" />
            div>
            <div class="content">
                <el-form :model="data" ref="form">
                    <el-form-item prop="username">
                        <el-input
                                @blur="usernameCheck"
                                v-model="data.username"
                                placeholder="用户名"
                                name="username"
                        >el-input>
                        <div class="infoMsg">
                            <p v-if="data.userMessage">{{ data.userMessage }}p>
                        div>
                    el-form-item>
                    <el-form-item prop="password">
                        <el-input
                                @blur="passwordCheck"
                                v-model="data.password"
                                placeholder="密码"
                                show-password
                                name="password"
                        >el-input>
                        <div class="infoMsg">
                            <p v-if="data.passwordMessage">{{ data.passwordMessage }}p>
                        div>
                    el-form-item>
                    <div v-if="showSliderCheck" class="sliderValidate">
                        <div
                                class="validateWrap"
                                ref="sliderWrap"
                                :class="{
                                validatePass: validPass
                            }"
                        >
                            <div class="block" ref="block">
                                <img
                                        v-show="validPass"
                                        src="@/assets/images/login/[email protected]"
                                        alt="滑块"
                                />
                                <i class="el-icon-d-arrow-right" v-show="!validPass">i>
                            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>
                        <span @click="$router.push({ name: 'reset' })">找回密码?span>
                    div>
                el-form>

                <a-button @click="clickLogin" class="loginButton" type="primary">登录a-button>
            div>
        div>
    div>
template>

<script>
	// 节流
    import { throttle } from "@/util/decorator";
	// 登陆密码加密
	import { submitEncrypt } from '@/utils/jsencrypt';    
	export default {
        data() {
            return {
                // 标示滑块校验是否通过
                validPass: false,
                // 登录表单
                data: {
                    username: "",
                    userMessage: "",
                    password: "",
                    passwordMessage: ""
                }
                // 显示滑块校验文字提示
                showSliderWarn: false
            };
        },
        methods: {
            /**
             * 为滑块添加事件
             */
            sliderEvent() {
                const sliderWrap = this.$refs.sliderWrap;
                const slider = this.$refs.block;
                if (!slider || !sliderWrap) return null;
                // 滑块容器的宽度
                const sliderBoxWidth = sliderWrap.clientWidth;
                // 滑块宽度
                const sliderWidth = slider.clientWidth;
                // 最大可拖动距离
                const maxSlideX = sliderBoxWidth - sliderWidth;
                // 滑块容器距离屏幕左边的距离(通过父级元素的offsetLeft计算)
                const formClientX = this.$refs.formWrap.offsetLeft + this.$refs.form.$el.offsetLeft;

                slider.onmousedown = e => {
                    const offsetX = e.offsetX;
                    if (this.validPass) {
                        return;
                    }
                    document.onmousemove = e => {
                        if (this.validPass) {
                            document.onmousemove = null;
                            document.onmouseup = null;
                            return;
                        }
                        const x = e.clientX - formClientX - offsetX;

                        if (x > 0 && x < maxSlideX) {
                            slider.style.left = x + "px";
                        }

                        if (x < 0) {
                            slider.style.left = "0px";
                        }

                        if (x > maxSlideX) {
                            slider.style.left = maxSlideX + "px";
                            this.validPass = true;
                            this.showSliderWarn = false;
                        }

                        if (x === maxSlideX) {
                            this.validPass = true;
                            this.showSliderWarn = false;
                        }
                    };
                    document.onmouseup = e => {
                        const centerX = sliderBoxWidth / 2 - 23;
                        let x = e.clientX - formClientX - offsetX;

                        let timer = null;

                        if (x <= centerX && x > 0) {
                            timer = setInterval(() => {
                                x -= 2;
                                if (x <= 0) {
                                    clearInterval(timer);
                                    slider.style.left = "0px";
                                }

                                slider.style.left = x + "px";
                            }, 1);
                        } else if (x > centerX && x < maxSlideX) {
                            timer = setInterval(() => {
                                x += 2;
                                if (x >= maxSlideX) {
                                    clearInterval(timer);
                                    slider.style.left = maxSlideX + "px";
                                    this.validPass = true;
                                    this.showSliderWarn = false;
                                }
                                slider.style.left = x + "px";
                            }, 1);
                        }
                        document.onmousemove = null;
                        document.onmouseup = null;
                    };
                };
            },
            /**
             * 用户名校验
             */
            async usernameCheck() {
                if (!this.data.username) {
                    this.data.userMessage = "请输入用户名";
                    return false;
                }
                if (!/^\w{5,20}$/g.test(this.data.username)) {
                    this.data.userMessage = "用户名不合法";
                    return false;
                }
            
                this.data.userMessage = "";
                return true;
            },
            /**
             * 密码校验
             */
            async passwordCheck() {
                if (!this.data.password) {
                    this.data.passwordMessage = "请输入密码";
                    return false;
                }
                this.data.passwordMessage = "";
                return true;
            },
            /**
             * 点击登陆
             */
                @throttle(2000)
            async clickLogin() {
                const usernameCheck = await this.usernameCheck();
                const passwordCheck = await this.passwordCheck();

                if (!usernameCheck || !passwordCheck) {
                    return null;
                }

                if (this.validPass || !this.showSliderCheck) {
                    this.showSliderWarn = false;
                    // 在账户和密码通过校验后, 判断当前账户是否已经登陆
                    await this.login();
                } else {
                    this.showSliderWarn = true;
                }
            },
            /**
             * 执行登陆
             */
            async login() {
                this.data.userMessage = "";
                this.data.passwordMessage = "";
                this.hideLoading = this.$message.loading("正在登录...", 30);
      			try{
      				const {data} = await login({
      					username:this.data.username,
      					password:submitEncrypt(this.data.password)
      				})
      				if(data.code){
      					//	成功
      				}else{
      					// 	失败
      				}
  
      			}catch(e){
      				console.log('e',e)
      			}
            },
         
        },
        mounted() {
            this.sliderEvent();
        }

    };
script>
<style lang="scss" scoped src="./_Login.scss">style>

你可能感兴趣的:(vue学习,前端,javascript,vue.js)