首先明白如何实现登录拦截,他的原理是什么?

这里主要用到的是路由拦截,在路由表里添加一个字段:requireAuth,用于判断该路由的访问是否需要登录;定义完路由后,我们主要是利用vue-router提供的钩子函数beforeEach()对路由进行判断。现在 我们开始......

首先科普下狗子函数:

每个钩子方法接收三个参数: 
* to: Route: 即将要进入的目标 路由对象 
* from: Route: 当前导航正要离开的路由 
* next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。 
* next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。 
* next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。 
* next(‘/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。

1、编写一个登录页面login.vue

<template>
  <el-container>
    <el-form :model="ruleLogin" status-icon :rules="loginRules" ref="ruleLogin" class="demo-ruleForm">
      <el-form-item  prop="userName">
        <el-input type="password" v-model="ruleLogin.userName" auto-complete="off" placeholder="请输入账号"></el-input>
      </el-form-item>
      <el-form-item  prop="passWord">
        <el-input type="password" v-model="ruleLogin.passWord" auto-complete="off" placeholder="请输入密码"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleLogin')">登录</el-button>
        <el-button @click="register()">注册</el-button>
      </el-form-item>
    </el-form>
  </el-container>
</template>
<script>
  export default {
    data() {
      var checkName = (rule, value, callback) => {
        if (!value) {
          return callback(new Error('用户名不能为空'));
        }
        callback();
      };
      var validatePass = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请输入密码'));
        } else {
          if (this.ruleLogin.passWord !== '') {
            callback();
          }
        }
      };
      return {
        ruleLogin: {
          userName:'',
          passWord: ''
        },
        loginRules: {
          userName: [
            { validator: checkName, trigger: 'blur' }
          ],
          passWord: [
            { validator: validatePass, trigger: 'blur' }
          ]
        }
      };
    },
    methods: {
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            alert('submit!');
          } else {
            console.log('error submit!!');
            return false;
          }
        });
      },
      register() {

      }
    }
  }
</script>
<style scoped lang="scss">
  .el-container{
    position: absolute;
    top:0;
    left:0;
    bottom:0;
    right: 0;
    display: flex;
    display: -webkit-flex;
    align-items: center;
    -webkit-align-items: center;
    justify-content: center;
    -webkit-justify-content: center;
    background-color: aquamarine;
    .el-form{
      border-radius: 20px;
      background-color: #ffffff;
      padding: 40px 30px;
      .el-form-item{
        display: flex;
        display: -webkit-flex;
        align-items: center;
        -webkit-align-items: center;
        justify-content: space-between;
        .el-input{
          flex:1;
          -webkit-flex: 1;
          width: 260px;
          display: flex;
          display: -webkit-flex;
          align-items: center;
          -webkit-align-items: center;
          input{
            flex:1;
            -webkit-flex: 1;
          }
        }

      }
    }
  }
</style>

2、修改路由,添加登录验证字段requireAuth

import Vue from 'vue'
import Router from 'vue-router'

import index from '@/views/index'//主页

import login from '@/views/login'//登录

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'index',
      component: index,
      meta:{
        requireAuth:true,// 添加该字段,表示进入这个路由是需要登录的
      }
    },
    {
      path:'/login',
      name:'登录',
      component:login
    }
  ]
})

3、现在实现简单的路由拦截:修改main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

import 'font-awesome/css/font-awesome.css'

Vue.use(ElementUI);

Vue.config.productionTip = false

//路由拦截器
router.beforeEach((to, from, next) => {
  if (to.meta.requireAuth) {  // 判断该路由是否需要登录权限
    next({
      path: '/login', // 将跳转的路由path作为参数,登录成功后跳转到该路由
    })
  }else {
    next();
  }
})


/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

到这里简单的路由拦截器已经实现了,有的同学会问,如何在本地保存登录状态呢?,如何在服务器保存登录状态?如何实现本地和服务器登录验证呢?比如tooken?

4、想实现本地保存登录信息tooken ,那我们先用下vuex吧,不明白的同学自行百度下

      (1)、安装vuex:   cnpm install vuex -S

    (2)、在main.js引入vuex:

import router from './router'//导入路由表
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

完整main.js:

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'

import router from './router'//导入路由表


import store from './store'//导入store

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

import 'font-awesome/css/font-awesome.css'

Vue.use(ElementUI);

Vue.config.productionTip = false

//路由拦截器
router.beforeEach((to, from, next) => {
  if (to.meta.requireAuth) {  // 判断该路由是否需要登录权限
    next({
      path: '/login', // 将跳转的路由path作为参数,登录成功后跳转到该路由
    })
  }else {
    next();
  }
})


/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

        (3)、store->index.js:

import Vue from 'vue'
import Vuex from 'vuex'


import user from './modules/user'//导入user

Vue.use(Vuex)//使用vuex

export default new Vuex.Store({
  modules: {
    user,
  },
  strict: process.env.NODE_ENV !== 'production', //在非生产环境下,使用严格模式
})

            store->modules->user.js

import Vue from 'vue'

export const USER_SIGNIN = 'USER_SIGNIN' //登录成功
export const USER_SIGNOUT = 'USER_SIGNOUT' //退出登录

export default {
  state: JSON.parse(sessionStorage.getItem('user')) || {},
  mutations: {
    [USER_SIGNIN](state, user) {
      sessionStorage.setItem('user', JSON.stringify(user))
      Object.assign(state, user)//Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
    },
    [USER_SIGNOUT](state) {
      sessionStorage.removeItem('user')
      Object.keys(state).forEach(k => Vue.delete(state, k))//Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 (两者的主要区别是 一个 for-in 循环还会枚举其原型链上的属性)。
    }
  },
  actions: {
    [USER_SIGNIN]({commit}, user) {
      commit(USER_SIGNIN, user)
    },
    [USER_SIGNOUT]({commit}) {
      commit(USER_SIGNOUT)
    }
  }
}
       修改login.vue组件,先导入

Logo

Vue社区为您提供最前沿的新闻资讯和知识内容

更多推荐