vue全局路由守卫

530 阅读2分钟

路由守卫,又叫导航守卫

全局的,单个路由独享的,或者组件级的。

下面是我写的全局前置守卫

重点:参数或查询的改变并不会触发进入/离开的导航守卫

全局守卫主要分为一下几个步骤:

1.配置登录页面

例如login.vue 是我们的登录页面

/src/router/index.js 配置我们的路由守卫页面

注意:路由守卫页面为一级路由

 {
        path: '/login',
        name: 'Login',
        component: () =>
            import ('../views/Login')
  }

2.配置路由守卫标识 配置路由元信息 meta

例如home.vue 是要守卫的页面

         {
                path: '/home',
                name: 'Home',
                meta: { islogin: true }, // 配置路由守卫标识    代表当前路由需要守卫  需要登陆权限
                component: () =>
                    import ('../views/Home')
         },

3.当进入路由页面时判断当前路由是否需要守卫

配置全局前置守卫函数: router.beforeEach()

router.beforeEach((to, from, next) => {
  // ...
})

参数:

to:即将要进入的目标 路由对象

from:当前导航正要离开的的路由

next:函数,决定是否展示你要看到的路由页面

4.判断当前用户的登陆状态

islogin:true 登陆直接查看

islogin:false 未登录 拦截到的登陆页面 login.vue 本地存储localStorage

router.beforeEach((to, from, next) => {
    // 判断即将进入的路由对象是否需要守卫
    if (to.meta.islogin) { // 需要守卫
        // 判断当前用户的登陆状态  登陆 直接查看next()  未登录  拦截到登陆页
        if (localStorage.getItem('token')) { // 登陆凭证token  
            next();
        } else { // 未登录
            next({
                path: '/login',
                query: {
                    topath: to.fullPath
                }
            });
        }
    } else {
        next(); // 接着执行
    }
})

5.实现登陆功能 进行表单处理

先写后端

const bodyParser = require('body-parser');
module.exports = {
    devServer:{
        before(app){
            // 使用中间件解析post传参
            app.use(bodyParser.json());
            app.use(bodyParser.urlencoded({extended:false}));
            app.post('/loginbtn',(req,res)=>{
                // 获取用户名和密码
                let obj = req.body;
                console.log(obj);
                // 根据前端的用户信息判断是否可以登陆 admin 123
                if(obj.name == 'admin' && obj.pwd == '123'){  // 用户信息正确
                    res.send({
                        code: 1,
                        token: '666',
                        text:'login success'
                    })
                }else{   // 用户信息不正确
                    res.send({
                        code: 0,
                        text:'login fail'
                    })
                }
            })
        }
    }
}

再写前端

<template>
  <div>
      <h2>登陆页面</h2>
      <div class="box">
          用户名:<input type="text" placeholder="请输入用户名" v-model="user">
      </div>
      <div class="box">
          密码:<input type="text" placeholder="请输入密码" v-model="pwd">
      </div>
      <!-- 登陆按钮绑定点击事件->获取用户名和密码->是否可以登陆 -->
      <button @click='gologin'>登陆</button>
  </div>
</template>
<script>
// 引入axios
import axios from 'axios'
export default {
    data(){
        return {
            user:'',// 用户名
            pwd:'', // 密码
        }
    },
    methods:{
        // 点击登陆
        gologin(){
            // 获取用户信息
            console.log(this.user);
            let obj = {
                name:this.user,
                pwd:this.pwd
            }
            // 判断当前用户是否可以登陆  
            axios.post('/loginbtn',obj).then(res=>{
                console.log(res.data);
            })
        }
    }
}
</script>

6.跳转路由拦截之前的页面 this.$router.push(路由路径)

 axios.post('/loginbtn',obj).then(res=>{
     console.log(res.data);
     if(res.data.code == 1){  // 成功
         // 存登陆凭证 跳转路由拦截之前的页面
         localStorage.setItem('token',res.data.token);
         this.$router.push(this.$route.query.topath);
     }else{
         alert('请检查你的用户名和密码');
     }
 })

另外

全局后置守卫

router.afterEach((to,from)=>{}) 只有两个参数

to:进入到哪个路由去

from:从哪个路由离开。

组件内守卫

到达这个组件时:beforeRouteEnter:(to,from,next)=>{}

beforeRouteEnter:(to,from,next)=>{
        next(vm=>{
            // 通过 `vm` 访问组件实例
            alert("hello" + vm.name);
        })
    }

离开这个组件时,beforeRouteLeave:(to,from,next)=>{}

beforeRouteLeave:(to,from,next)=>{
        if(confirm("确定离开此页面吗?") == true){
            next();
        }else{
            next(false);
        }
    }

v2-b6430199eb1fae75fa0ee3bd35c2082c_720w.jpg