• vue中 router.beforeEach() 的用法


    导航守卫 主要是通过跳转或取消得方式守卫导航

    1. 在前端路由跳转中,路由跳转前都是会经过beforeEach,而beforeEach可以通过next来控制到底去哪个路由。
    2. 根据这个特性我们就可以在beforeEach中设置一些条件来控制路由的重定向。

    常见的使用场景有:

    1. 1、验证用户是否登录(若未登录,且当前非登录页面,则自动重定向登录页面);
    2. 2、用户权限;
    3. 3、用户输入的路路径是否存在,不存在的情况下如何处理,重定向到哪个页面。

    此处呢我使用一个简单的例子:
    当用户输入的路径不存在的情况下,将其重定向到‘/’路径来说明beforeEach是如何控制路由的。

    话不多说,直接看下边如何实现的(这里我以创建一个名为router-be的项目为例)。

    第一步 : 规定进入路由是否需要权限

    @/router/index.js

    import A from '@/components/a'
    {
    	path : '/a',
    	name : 'a',
    	component : A,
    	meta : {  // 加一个自定义obj
    		requireAuth : true   // 参数 true 代表需要登陆才能进入 A
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    第二步 : 使用vuex 整一个useid

    @/assets/store.js

    //使用vuex三步走
    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    //这个理论来说
    const store = new Vuex.Store({
    	state:{
    		userId : ''
    	}
    })
    
    export default store
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    第三步 : 使用router.beforeEach()

    思路:【
    	如果(进入这个路由需要权限){
    	
    		如果(能获取到这个用户的userID){
    			就让这个用户进入这个路由
    		}否则{
    			就让这个用户进入b这个页面
    		}
    		
    	} 即将进入的路由不需要权限就能进入 {
    	
    		就让这个用户进入这个路由
    		
    	}
    】
    对应代码:
    import store from '@/assets/store'   //把这个userId获取过来
    router.beforeEach((to,from,next)=>{
    	if(to.meta.requireAuth){
    		if(store.state.userId){
    			next()
    		}else{
    			next({path:'/b'})
    		}
    	}else{
    		next()
    	}
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    实现原理

    1. constrouter=newVueRouter({…})
    2. router.beforeEach((to,from,next)=>{// …})
    3. 每个守卫方法接受三个参数 :

    1.to => route : 即将进入的目标路由对象
    2.from => route : 当前导航正要离开的路由
    3.next => function: 一定要调用该方法来 resolve这个钩子,执行效果以来 next 方法的调用参数

    第四步

    1. 上一步 /b 路由为 登陆页面
    2. 当进入A 页面之前,需要先请求接口,获取是否有登录,然后把userId存在vuex 的state 中
    3. 当没有userId 时,则在登录之后,存一个userId 到state 里

    第五步 项目中使用

    router.beforeEach((to, from, next) => {
      console.log(to);
    
      // DEBUG: 测试
      return next();
    
      const { ldomain } = to.query;
      if (ldomain) {
        document.domain = ldomain;
      }
    
      const { LoginPage } = byskConfig;
    
      if (!router.getMatchedComponents(to.path).length) {
        console.log("not page", to, from);
        return next(byskConfig.NotFoundPage.path);
      }
    
      //验证权限
      if (to.meta.permId && !hasPerms(to.meta.permId)) {
        console.log("no auth", to, from);
        return next(LoginPage.path);
      }
    
      //验证是否登录
      if (to.meta.permId && !getCookie("sid")) {
        console.log("no login & signout", to, from);
        return next(LoginPage.path);
      }
    
      if (to.matched.length) {
        let parentRoute = to.matched[to.matched.length - 1].parent;
        if (
          parentRoute &&
          parentRoute.meta.hasOwnProperty("redirect") &&
          parentRoute.meta.redirect !== to.path) {
          parentRoute.meta.redirect = to.path;
        }
      }
      next();
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    权限

    export function setupPermissionGuard(router) {
      router.beforeEach(async (to, from, next) => {
        const { state, commit, dispatch } = store;
        // TODO: 404 的处理
    
        // 不需要登录,可访问
        if (to.meta.ignoreAuth === true) {
          next();
          return;
        }
    
        // TODO: 白名单
    
        // 刷新重新登录
        if (!state.appToken) {
          await dispatch('relogin');
        }
    
        // 处理token
        const hasToken = !!state.appToken;
    
        if (!hasToken) { // 未登陆,或过期
          // 重定向到登录页
          const redirectData = {
            path: LOGIN_PATH,
            replace: true,
          };
    
          next(redirectData);
          return;
        }
    
        // 判断是否有权限
        const hasAuthority = to.meta.permId && hasPerms(to.meta.permId);
    
        if (hasAuthority) { // 权限验证
          if (to.meta.ignoreKeepAlive !== true) {
            // 页面需要缓存, 添加到缓存
            const { cachePages } = state;
            const { matched } = to;
            commit('setCachePages', [...cachePages, ...matched.slice(1)]);
          }
    
          next();
          return;
        }
        next(from.path);
    
        // next();
      });
    
      router.afterEach((to) => {
        if (to.meta?.label) {
          // 设置页面`title`
          document.title = `一立科技 - ${to.meta.label}`;
        }
      });
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    Day2力扣打卡
    一款开源的文件搜索神器,终于不用记 find 命令了
    Next.js Web 应用程序 SSG 与 SSR——选择正确的渲染方法
    python+request+excel做接口自动化测试
    代理模式——设计模式
    如何快速掌握Vuex
    docker安装RabbitMQ
    MAC帧
    ASEMI肖特基二极管1N5822参数,1N5822特征,1N5822应用
    测试 Apache Flink SQL 代码
  • 原文地址:https://blog.csdn.net/seimeii/article/details/126261606