JavaScript系列—用戶登錄退出cookies—vue版

這篇文章我們結合vue和vue-router來說一下如何實現用戶的登錄,退出,和cookies

先回憶一下之前《vue-router—14案例:模擬登錄跳轉》這篇文章

1. vue-router—14案例:模擬登錄跳轉

首先封裝一下插件(關於爲什麼這麼封裝,爲什麼會有install,可以參考這篇博文https://www.cnblogs.com/mengfangui/p/9046525.html)

utils.js

/**
 * Vue的插件,用來獲取和設置localStorage存儲
 **/
let local = {
  save (key, value) {
    localStorage.setItem(key, JSON.stringify(value))
  },
  fetch (key) {
    return JSON.parse(localStorage.getItem(key)) || {}
  }
}

export default {
  install: function (vm) {
    vm.prototype.$local = local
  }
}

然後在main.js中use

 然後在router.js中全局路由鉤子中判斷

router.beforeEach((to, from, next) => {
  
  let b1 = to.matched.some(item => item.meta.login)
  if(b1) { // matched這個字段包含了所有的相關的節點,假如有任何一個節點有{login:true}
    // 獲取到緩存裏面的用戶的字段
    let info = router.app.$local.fetch("miaov")
    if(info.login){ //如果是已經登錄狀態
      next();
    }else{  //如果是登出狀態
      // 此處跳轉到登錄界面,並且新增加一個字段,記錄用戶一開始想去的路由
      router.push({
        path: '/login',
        query: {
          redirect: to.path.slice(1)
        }
      })
    }

  }else{ // matched這個字段包含了所有的相關的節點,沒有任何一個節點包含login,那麼就不用管了
    next()
  }
  
})

現在就到了登錄界面login.vue

<template>
  <div class="login">
    <div class="login-box">
      <h2>登錄</h2>
      <form @submit.prevent='sendLogin' autocomplete="off">
        <div><input placeholder="請輸入用戶名" type="text" name="user" ref="userInput" /></div>
        <div><input placeholder="請輸入密碼" type="password" name="password" /></div>
        <div class="login-btn"><input type="submit" value="一鍵登入" /></div>
      </form>
      <div class="back-index">
        <router-link  to="/">首頁>>></router-link>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'login',
    data () {
      return {}
    },
    methods: {
      sendLogin () {

        // 點擊登錄
        let userName = this.$refs.userInput.value;
        // 向緩存中保存用戶信息
        this.$local.save("miaov", {
            login: true,
            userName: userName
        })
        // 獲取在全局路由鉤子中記錄的用戶一開始想去的路由界面
        let redirect = this.$route.query.redirect
        // 如果沒有記錄,那就默認進project這個路由界面
        if(!redirect){
          redirect = 'project'
        }
        // 跳轉路由
        this.$router.push({
          path: '/'+redirect
        })
      }
    }
  }
</script>
<style>

</style>

接下來就是home.vue這塊

如果從緩存中獲取到信息,則就顯示用戶的姓名和圖標,如果沒有,那麼顯示登錄兩個字

<template>
  <div class="main">
    <div class="home-header">
      <img src="../assets/miaov.png" alt="">
      <div class="portrait" :class={portraitLogin:isLogin}>
        <router-link  v-if="!isLogin" to="/login" tag="span">登錄</router-link>
        <img  v-if="isLogin" src="../assets/portrait.png" alt="">
      </div>

    </div>
    <div class="phrase">
      一起學習Vue-router
    </div>
    <div class="btns">
      <router-link to="/project" tag="div" class=" trans">我的項目</router-link>
      <router-link to="/doc" tag="div" class=" trans">我的文檔</router-link>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'home',
    data () {
      return {
        isLogin: false
      }
    },
    created(){
        // 拿到登錄信息
      let info = this.$local.fetch('miaov')

      this.isLogin = info.login;
    }
  }
</script>
<style>

</style>

下來是這塊的顯示以及退出

header,vue

<template>
  <div class="clearFix el-menu--dark">
    <ul class="el-menu menu-horizontal el-menu--dark el-menu--horizontal header-nav" >
      <router-link to="/" class="el-menu-item logo" exact tag="li">
      <img src="../assets/miaov.png">
    </router-link>
      <router-link to="/project" class="el-menu-item" tag="li" >
        <i class="fa fa-home"></i>
        我的項目
      </router-link>
      <router-link to='/workbench' class="el-menu-item"  tag="li">
        <i class="fa fa-code"></i>
        工作臺
      </router-link>
      <router-link to="/doc" class="el-menu-item" tag="li">
        <i class="fa fa-book"></i>
        文檔
      </router-link>
    </ul>
    <div class="user-info-box" v-show="isLogin">
      <div class="el-submenu__title">
        <img src="../assets/portrait.png">
        <span>{{userName}}</span>
      </div>
      <div class="header-menu">
        <ul class="menu-nav">
          <li class="el-menu-item" @click="loginOut">登出</li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'Header',
    data () {
      return {
        userName: '',
        isLogin: false
      }
    },
    created(){
      let info = this.$local.fetch("miaov")
      this.isLogin = info.login;
      this.userName = info.userName
    },
    methods: {
      loginOut(){
        this.$local.save("miaov", null)
        this.$router.push("/login")
      }
    }
  }
</script>
<style>

</style>

 2.實際項目

下來分析一下我們的協同項目中登錄登出是怎麼寫

login.vue

<template>
    <div class="login">
        <div>
            <div class="hd-logo"></div>
            <div class="header">{{this.tenantName}}3D雲設計平臺</div>
            <el-form :model="login">
                <div style="width: 324px;margin: auto;">
                    <el-row>
                        <el-col>
                            <el-input v-model="login.email" placeholder="請輸入郵箱賬號"></el-input>
                        </el-col>
                    </el-row>

                    <el-row>
                        <el-col>
                            <el-input type="password" v-model="login.password" placeholder="請輸入密碼"></el-input>
                        </el-col>
                    </el-row>

                    <el-row v-if="isValidateCodePicFlag" >
                        <el-col style="display: flex">
                            <el-input v-model="login.validateCode" placeholder="請輸入驗證碼" style="width: 200px;"></el-input>
                            <img :src="validateImg" style="display:  inline-block; border:  solid 1px black; width:  100px; height: 34px; margin-left: 20px;
">
                        </el-col>
                    </el-row>

                    <div class="forget-choose">
                        <el-checkbox class="remember-me" v-model="login.rememberMe">記住我</el-checkbox>
                        <!--<div class="forget-password" @click="passwordVisible = true">忘記密碼?</div>-->
                    </div>

                    <el-row>
                        <el-col>
                            <el-button type="primary" @click="onSubmit">登錄</el-button>
                        </el-col>
                    </el-row>
                </div>

            </el-form>
        </div>
    </div>
</template>
        created() {
            if (Cookies.get('rememberMe') === true || Cookies.get('rememberMe') === 'true') {
                this.login.rememberMe = true;
            }

            if(this.login.rememberMe){
                this.login.password = Cookies.get('password');
                this.login.email = Cookies.get('userEmail');
            }else{
                this.login.email = '';
                this.login.password = '';
            }
        },
        mounted(){
            const self = this;
            document.onkeypress = function (event) {
                if(self.passwordVisible == false){
                    if(event.keyCode == 13 && self.$route.path === '/login'){
                        self.onSubmit();
                    }
                }

            }
        },
        watch: {
            'login.rememberMe'(val){
                this.$store.commit(types.REMEBER_ME_ACCOUNT, {data: val});
            }
        },
        methods: {
            onSubmit() {
                if(!this.login.email || !this.login.password){
                    this.$message.info("請輸入賬號或密碼");
                    return;
                }

                if(this.isValidateCodePicFlag && !this.login.validateCode){
                    this.$message.info("請輸入驗證碼");
                    return;
                }

                if(this.isValidateCodePicFlag && this.login.validateCode.length !== 6){
                    this.$message.info("驗證碼輸入不正確");
                    return;
                }

                const loginData = `username=${this.login.email}&password=${this.login.password}&client_id=planner_jim&client_secret=7890ab&grant_type=password&scopes=bio notes`;
                let params = {
                    UserName: this.login.email,
                    Password: this.login.password,
                    VerificationCode: this.login.validateCode,
                    VerificationCodeId: this.login.validateImgId,
                }
                Request.validatelogin(params, (data) => {
                    if(data.er === -1) {
                        Cookies.set('access_token', data.items.access_token);
                        Cookies.set('refresh_token', data.items.refresh_token);
                        Cookies.remove('loginemail');
                        Cookies.remove('userEmail');
                        Cookies.remove('password');
                        Cookies.remove('rememberMe');
                        Cookies.set('loginemail',this.login.email, {expires:7,path:'/'});
                        Cookies.set('userEmail',this.login.email, {expires:7,path:'/'});
                        Cookies.set('password',this.login.password, {expires:7,path:'/'});
                        if(this.login.rememberMe){
                            Cookies.set('rememberMe',true, {expires:7,path:'/'});
                        } else {
                            Cookies.set('rememberMe',false, {expires:7,path:'/'});
                        }

                        this.$store.commit(types.USER_TOKEN, {data: data});
                        this.$store.commit(types.GET_PROJECT_PROPOSAL_BY_ORG_ID, {data: []});
                        this.$router.push({path: '/chooseProject'});
                    }else if(data.er === -25) {
                        this.$message.info('賬號密碼錯誤!');
                        if(this.isValidateCodePicFlag) {
                            this.getImgValidateCode();
                        }
                    }else if(data.er === -26) {
                        Cookies.remove('loginemail');
                        Cookies.set('loginemail',this.login.email, {expires:7,path:'/'});
                        this.$router.push({path: '/chooseProject',query: {reset: true}})
                    }else if(data.er === 429) {
                        this.$message.info('賬號密碼錯誤!');
                        this.isValidateCodePicFlag = true;
                        this.getImgValidateCode();
                    }else if(data.er === -21) {
                        this.isValidateCodePicFlag = true;
                        this.$message.info('驗證碼錯誤!');
                        this.getImgValidateCode()
                    }

                }, (err) => {

                });
            },

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章