用 Vue 实现记住登录信息功能

前言

最近做练习的时候遇到了记住登录用户信息的需求,我查了一些资料、看过几个人的博客,但是我看到的文章不是有错误就是格式及其糟糕,为此我会将我实现的原理用尽可能通俗易懂的方式告诉大家。

使用的依赖

  • ant-design-vue
  • js-base64

实现原理

用 Vue 实现记住登录信息功能_第1张图片
如图所示,我们需要根据用户是否点击记住信息来决定是否保存用户信息;

当用户决定要保存登录信息的时候,我们将使用cookie来保存信息,当然在保存密码前我们需要用js-base64对其进行加密;

要注意的是在获取密码前要先对cookie中加密的密码进行解密再保存在组件的数据中,最后通过数据渲染视图;

代码

注意: 关于template部分的代码可选择跳过,源码请查询官方文档( 表单/登录框 )
https://www.antdv.com/components/form-cn/#components-form-demo-login-form

重点是看script中定义的方法组件生命周期函数
建议观看顺序:setCookie–》getCookie–》initForm–》handleSubmit–》created

<template>
    <a-form
            id="components-form-demo-normal-login"
            :form="form"
            class="login-form"
            @submit="handleSubmit">
        <a-form-item>
            <a-input
                    v-decorator="['userName',{
                      rules: [
                          {
                              required: true,
                              message: '请输入用户名!'
                          },
                          {
                              min: 5,
                              message: '用户名最小长度为5位'
                          },
                          {
                              max: 12,
                              message:'用户名长度不可超过12位'
                          }],
                        initialValue: username
                    }]"
                    placeholder="username">
                <a-icon slot="prefix" type="user" style="color: rgba(0,0,0,.25)" />
            a-input>
        a-form-item>
        <a-form-item>
            <a-input
                    v-decorator="['password',{
                        rules: [
                            {
                                required: true,
                                message: '请输入密码!'
                            },
                            {
                                min: 8,
                                message: '密码最低长度为8位'
                            },
                            {
                                max: 16,
                                message: '密码长度不可超过16位'
                            }],
                        initialValue: psd
                    }]"
                    type="password"
                    placeholder="Password">
                <a-icon slot="prefix" type="lock" style="color: rgba(0,0,0,.25)" />
            a-input>
        a-form-item>
        <a-form-item>
            <a-checkbox
                    v-decorator="['remember',{
			            valuePropName: 'checked',
			            initialValue: true,
			          },
			        ]">
                Remember me
            a-checkbox>
            <a class="login-form-forgot" href="">
                Forgot password
            a>
            <a-button type="primary" html-type="submit" class="login-form-button">
                Log in
            a-button>
        a-form-item>
    a-form>
template>

<script lang="ts">
    import {Vue, Component} from "vue-property-decorator";
    // 引入base64
    import { Base64 } from 'js-base64';
    
    @Component({})
    export default class LoginField extends Vue {
        /* 自定义数据 */
        form:any = null;
        username:string = '';
        psd:string = '';

        /* 自定义函数 */
        // 提交表单时做的事情
        handleSubmit(e) {
            e.preventDefault();
            // console.log(this.form);
            this.form.validateFields(async (err, values) => {
                if (!err) {
                    // console.log('Received values of form: ', values);
                    const data = {
                        username: values.userName
                        ,password: values.password
                    };

                    const {data:{access_token}} = await this.$http.post('/login', data);
                    if( access_token ){
                        // 判断是否需要记录登录状态
                        if( values.remember ){
                            this.setCookie("username", data.username, 30);
                            const psd = Base64.encode(data.password);
                            this.setCookie('psd', psd, 30);
                        } else{
                            this.setCookie('username','', 0);
                            this.setCookie('psd', '', 0);
                        }
                        // 登录成功后要做的事情
                        this.$message.success('登录成功!');
                        this.$router.push('/home');
                    } else{
                        this.$message.error('登录异常,请稍后再试!');
                    }
                }
            });
        };

        // 组件创建时初始化表单数据
        initForm(){
            const username = this.getCookie('username');
            const psd = this.getCookie('psd');
            if( username && psd ){
                this.username = username;
                this.psd = psd;
            }
        };

        // 设置 cookie
        setCookie(cName, value, expireDays){
            let exDate:any = new Date();
            exDate = exDate.setDate(exDate.getDate() + expireDays);
            document.cookie = cName + '='
                + value
                + ((expireDays === undefined) ? '' : ';expires=' + new Date(exDate).toUTCString())
        }

        // 获取 cookie
        getCookie(key){
            if( document.cookie.length > 0 ){
                let start = document.cookie.indexOf(key + '=');
                if( start !== -1 ){
                    start = start + key.length + 1;
                    let end = document.cookie.indexOf(';', start);

                    if( end === -1 ){
                        end = document.cookie.length;
                        return Base64.decode(document.cookie.substring(start, end));
                    } else{
                        return document.cookie.substring(start, end);
                    }
                }
            }
            return ''
        }

        /* 组件生命周期 */
        created() {
        	// this.form 是UI框架中登录框的源码之一,研究代码时可以忽略
            this.form = this.$form.createForm(this, { props: { name: 'normal_login' } });
            this.initForm()
        };
    }
script>

<style scoped lang="less">
    #components-form-demo-normal-login .login-form {
        max-width: 300px;
    }
    #components-form-demo-normal-login .login-form-forgot {
        float: right;
    }
    #components-form-demo-normal-login .login-form-button {
        width: 100%;
    }
style>

代码备注:

  • Cookie 用于存储 web 页面的用户信息 ,设置Cookie是以键值对的形式设置的,如:
    document.cookie="username=John Doe";
    当然也可以给它加上一个过期时间,如:
    document.cookie="username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT";
    为了实现长时间记住用户信息的功能,这个过期时间是必须的,否则Cookie默认在浏览器关闭时消除;
  • 通过document.cookie获取到的数据是一个字符串,信息将会以键值对的形式存储,键值对之间会以分号隔开,最后一个键值对后是没有分号的,此时在代码中的表现就是 end === -1。至于代码中的一些字符串操作在这里就不累述了;
  • 数据是在 created中获取,因此当数据获取完毕后组件还没渲染,所以当组件渲染完毕后数据是能正常显示的;
  • 这个vue组件是用typeScript写的,可能没学过typeScript或者没用过typeScriptvue的小伙伴会有一些困惑;而我书写代码的时候通过注释手动分开了代码区,大家只要着重研究函数就行,而且这个和vue2.0写法差不多,大家有一定vue基础的话应该都没问题的;

参考资料

  • https://www.cnblogs.com/qisi007/p/10200140.html
  • https://www.runoob.com/js/js-cookies.html

后记

当然实现记住用户信息的方法不唯一,对文章有问题或者对实现功能有不同想法的小伙伴可以在评论区留言,欢迎不同的声音!!

你可能感兴趣的:(VueJS)