vue实现登录+记住密码+验证码+密码明文暗文

废话不多说,直接上代码。。。。。。。。。。
login文件

<template>
    <div class="sigin background" :style="{height:cHeight+'px'}">
        <div class="wrapper">
            <div class="text-img">
                <img :src="title" alt="">
            </div>
            <div class="login">
                <div class="input-wrap">
                    <span class="input-lable">用户名</span>
                    <span class="input-ped"><input type="text" v-model="loginForm.userName"
                            autocomplete="username"></span>
                </div>
                <div class="input-wrap">
                    <span class="input-lable">密&nbsp;&nbsp;&nbsp;&nbsp;码</span>
                    <span class="input-ped"><input :type="flag !== true?'password':'text'" v-model="loginForm.password"
                            autocomplete="current-password"></span>
                    <img style="margin-right:0px;" :src="this.registration_data.src" @click="changeType()" />
                </div>
                <div class="login-code">
                    <div class="input-wrap">
                        <span class="input-lable">验证码</span>
                        <span class="input-ped"><input type="password" v-model="loginForm.code"
                                autocomplete="current-password"></span>
                    </div>
                    <div class="code" @click="refreshCode">
                        <!--使用验证码组件-->
                        <s-identify :identifyCode="identifyCode"></s-identify>
                    </div>
                </div>

                <div class="remember">
                    <input type="checkbox" v-model="checked" style="margin-right:5px;"><span>记住密码</span>
                </div>

                <button class="log-btn" @click="login">登录</button>
            </div>
        </div>
        <router-view />
    </div>
</template>

<script>
import { getUserLogin, getCountNoReadForApp } from '@/api';
import { mapMutations } from 'vuex';
import SIdentify from '@/components/canvas/sIdentify.vue'; //引用验证码组件
import title from '../../assets/title.png';

export default {
    name: '',
    data() {
        return {
            title,
            flag: false,
            checked: false, // 默认不记住密码
            loginForm: {
                 userName: '',
                 password: '',
                code: ''
            },
            registration_data: {
                pwdType: 'password',
                src: require('../../assets/closeeyes.png')
            },
            identifyCode: '',
            identifyCodes: '1234567890abcdefghijklinopqrsduvwxyz', //  1234567890ABCDEFGHIJKLINOPQRSDUVWXYZ
            cHeight: null,

        };
    },
    filters: {},
    mounted() {
        // // 初始化验证码
        this.identifyCode = '1234';
        // this.makeCode(this.identifyCodes, 4)
    },
  
    created() {
        this.cHeight = window.innerHeight;

        // 在页面加载时从localStorage获取登录信息
        const userName = localStorage.getItem('userName');
        const password = localStorage.getItem('password');
        //判断用户是否点击了记住密码
        if (localStorage.getItem('checked') === 'true') {
            this.loginForm.userName = userName;
            this.loginForm.password = password;
            this.checked = true;
        }
    },
    components: { SIdentify }, //注册验证码组件
    methods: {
        ...mapMutations(['changeLogin']),
        // 点击刷新验证码
        refreshCode() {
            this.identifyCode = '';
            this.makeCode(this.identifyCode, 4);
        },
       //生成随机的四位数验证码
        makeCode(o, l) {
            for (let i = 0; i < l; i++) {
                this.identifyCode += this.identifyCodes[
                    this.randomNum(0, this.identifyCodes.length)
                ];
            }
        },
        randomNum(min, max) {
            return Math.floor(Math.random() * (max - min) + min);
        },
        // 是否显示输入的密码
        changeType() {
            this.flag = !this.flag;
            if (this.flag == true) {
                this.registration_data.src = require('../../assets/openeyes.png');
            } else {
                this.registration_data.src = require('../../assets/closeeyes.png');
            }
        },
        // 登录
        login() {
            if (!this.loginForm.userName) {
                this.ShowToast('账号不能为空');
                return;
            }
            if (!this.loginForm.password) {
                this.ShowToast('密码不能为空');
                return;
            }
            if (this.loginForm.code !== this.identifyCode) {
                this.ShowToast('请填写正确验证码');
                this.refreshCode();
                return;
            }
           this.getUserLoginFn(this.loginForm.userName, this.loginForm.password);
        },

        getUserLoginFn(userName, password) {
            this.ShowLoading();
            getUserLogin({
                username: userName,
                password
            }).then((res) => {
                this.HideLoading();
                this.setUserInfo();
                // 这里是因为要在created中判断,所以使用localstorage比较简单
                localStorage.setItem('checked', this.checked);
                this.$store.commit('setUserInfo', res.data.user);// 用户信息
                this.$store.commit('setPermissions', res.data.permissions);// 权限
                this.$store.commit('setExipreTime', res.data.exipreTime);// token过期时间
                this.$store.commit('setReOutUserId', res.data.user.id);// 退出时用的id
                this.changeLogin({ Authorization: res.data.token });// token
                // 跳转登录
                this.$router.push({
                    name: 'home'
                });
            }).catch((err) => {
                this.HideLoading();
                this.ShowToast('账号或密码错误,登录失败');
                console.log(err);
            });
        },
        // 是否记住密码
        setUserInfo() {
            // 判断用户是否勾选记住密码,如果勾选,向localStorage中储存登录信息,
            // 如果没有勾选,储存的信息为空
            if (this.checked === true) {
                localStorage.setItem('userName', this.loginForm.userName);
                localStorage.setItem('password', this.loginForm.password);
            } else {
                localStorage.setItem('userName', '');
                localStorage.setItem('password', '');
            }
        },
    },
};
</script>

因为字段太多,没有上css样式,大家自行书写css样式楼~~~

接下来放上验证码组件 sIdentify.vue,,,,,

<template>
    <div class="s-canvas">
        <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
    </div>
</template>
<script>
export default {
    name: 'SIdentify',
    props: {
        identifyCode: {
            type: String,
            default: '1234'
        },
        fontSizeMin: {
            type: Number,
            default: 25
        },
        fontSizeMax: {
            type: Number,
            default: 30
        },
        backgroundColorMin: {
            type: Number,
            default: 255
        },
        backgroundColorMax: {
            type: Number,
            default: 255
        },
        colorMin: {
            type: Number,
            default: 0
        },
        colorMax: {
            type: Number,
            default: 160
        },
        lineColorMin: {
            type: Number,
            default: 100
        },
        lineColorMax: {
            type: Number,
            default: 255
        },
        dotColorMin: {
            type: Number,
            default: 0
        },
        dotColorMax: {
            type: Number,
            default: 255
        },
        contentWidth: {
            type: Number,
            default: 100
        },
        contentHeight: {
            type: Number,
            default: 30
        }
    },
    methods: {
        // 生成一个随机数
        randomNum(min, max) {
            return Math.floor(Math.random() * (max - min) + min);
        },
        // 生成一个随机的颜色
        randomColor(min, max) {
            const r = this.randomNum(min, max);
            const g = this.randomNum(min, max);
            const b = this.randomNum(min, max);
            return `rgb(${r},${g},${b})`;
        },
        drawPic() {
            const canvas = document.getElementById('s-canvas');
            const ctx = canvas.getContext('2d');
            ctx.textBaseline = 'bottom';
            // 绘制背景
            ctx.fillStyle = this.randomColor(this.backgroundColorMin, this.backgroundColorMax);
            ctx.fillRect(0, 0, this.contentWidth, this.contentHeight);
            // 绘制文字
            for (let i = 0; i < this.identifyCode.length; i++) {
                this.drawText(ctx, this.identifyCode[i], i);
            }
            this.drawLine(ctx);
            this.drawDot(ctx);
        },
        drawText(ctx, txt, i) {
            ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax);
            ctx.font = `${this.randomNum(this.fontSizeMin, this.fontSizeMax)}px SimHei`;
            const x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1));
            const y = this.randomNum(this.fontSizeMax, this.contentHeight - 5);
            const deg = this.randomNum(-45, 45);
            // 修改坐标原点和旋转角度
            ctx.translate(x, y);
            ctx.rotate(deg * Math.PI / 180);
            ctx.fillText(txt, 0, 0);
            // 恢复坐标原点和旋转角度
            ctx.rotate(-deg * Math.PI / 180);
            ctx.translate(-x, -y);
        },
        drawLine(ctx) {
            // 绘制干扰线
            for (let i = 0; i < 5; i++) {
                ctx.strokeStyle = this.randomColor(this.lineColorMin, this.lineColorMax);
                ctx.beginPath();
                ctx.moveTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight));
                ctx.lineTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight));
                ctx.stroke();
            }
        },
        drawDot(ctx) {
            // 绘制干扰点
            for (let i = 0; i < 80; i++) {
                ctx.fillStyle = this.randomColor(0, 255);
                ctx.beginPath();
                ctx.arc(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight), 1, 0, 2 * Math.PI);
                ctx.fill();
            }
        }
    },
    watch: {
        identifyCode() {
            this.drawPic();
        }
    },
    mounted() {
        this.drawPic();
    }
};
</script>
<style scoped>
.s-canvas {
    height: 38px;
}
</style>

哦了~~~~~~~~~~有需要的自行查看吧!希望能够帮到正在工作中的你~加油!!

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容