路由守卫

136 阅读3分钟

个人关于路由守卫的理解

完整的导航解析流程
  1. 导航被触发。
  2. 在失活的组件里调用 beforeRouteLeave 卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,

安装命令

npm i nprogress --save/npm i NProgress -S

注册到 package.json的dependencies

npm i NProgress --save-dev/npm i NProgress -D

注册到 package.json的devDependencies

每个守卫方法接收两个参数:

全局路由守卫

beforeEnter 守卫 只在进入路由时触发,不会在 paramsquery 或 hash 改变时触发。例如,从 /users/2 进入到 /users/3 或者从 /users/2#info 进入到 /users/2#projects。它们只有在 从一个不同的 路由导航时,才会被触发

import NProgress from "nprogress";
import 'nprogress/nprogress.css';
 // 路由跳转前
router.beforeEach((to, from, next) => {
  NProgress.start();  
  // 路由进度条开始
  if (to.meta.title) {
  //判读路由跳转前是否有title标题
    document.title = to.meta.title
    //浏览器标题文字切换成路由给的标题文字
  }
  next()
  // return false 返回 false 以取消导航 
})
// 路由跳转中
router.beforeResolve((to, from, next) => {
  next()
  //不加next() 就会中断执行
})
// 路由跳转后
router.afterEach((to, from) => {
  NProgress.done();
  // 路由进度条结束
})

路由独享守卫

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView,
    meta: {
      title: '首页',
    }
  },
  {
    path: '/login',
    name: 'login',
    component: () => import('../views/Login.vue'),
    meta: {
      title: '登录',
    }
  },
  {
    path: '/about',
    name: 'about',
 
    component: () => import('../views/AboutView.vue'),
    meta: {
      title: 'About页',
    },
    beforeEnter(to, from, next) {
      let token = sessionStorage.getItem('token');
      //判断本地是否存在token 
      if (token) {
        next()
        //如果存在就让执行下一部
      } else {
        next('/login')
        //如果不存在就跳转会登录页面
      }
    }
  }
]

组件内部守卫

注意 beforeRouteEnter 是支持给 next 传递回调的唯一守卫。对于 beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经可用了,所以不支持 传递回调,因为没有必要了:


  beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被验证前调用
    // 不能获取组件实例 `this` ! 
    // 因为当守卫执行时,组件实例还没被创建!
    next((vm) => {
      console.log(vm.name, "name");
      //如果需要用到this 用next(vm)用vm代替this
  },
  beforeRouteUpdate(to, from) {
  // 在当前路由改变,但是该组件被复用时调用 
  // 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候, 
  // 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 
  // 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
  },
  beforeRouteLeave(to, from) {
 // 在导航离开渲染该组件的对应路由时调用 
 // 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
   //这个 **离开守卫** 通常用来预防用户在还未保存修改前突然离开。该导航可以通过返回 `false` 来取消。
  },