Vue-router路由守卫触发顺序详解

1,240

官方文档: 导航守卫

路由守卫有哪些

全局路由钩子:

  • beforeEach (to, from, next)
  • beforeResolve(to, from, next)
  • afterEach(to, from) 不会接收next,也不会改变导航本身

路由独享守卫:

  • beforeEnter(to, from, next) 写在配置文件中
const routes = [
    {
        path: "/",
        name: "layout",
        beforeEnter(to, from, next) {
                // ...
        }
    }
]

组件路由守卫:

  • beforeRouteEnter(to, from, next) 无法获得this,可以使用next(vm => {})传递一个回调函数
  • beforeRouteUpdate(to, from, next)
  • beforeRouteLeave(to, from, next)

beforeRouteUpdate和beforeRouteEnter的区别

路由跳转时如果匹配到的是同一条规则,则会触发beforeRouteUpdate,如果匹配的是不同规则,则会触发beforeRouteEnter

举例:

  • /user => /about 触发About组件的beforeRouteEnter
  • /user/1 => /user/2 触发user组件的beforeRouteUpdate

这里还有一个疑惑点,如果路由规则这样写会怎么样:

const routes = [
    {
        path: "/user/:id",
        name: "user",
        component: User,
        props: true
    },
    {
        path: "/user",
        name: "user",
        component: User
    }
]

/user => /user/1 由于这个路由跳转匹配了两个不同的规则,所以会触发beforeRouteEnter

路由导航触发顺序

在路由导航触发时,有两个组件的路由钩子以及全局的钩子函数会被调用,两个组件分别是失活的组件激活的组件,顺序如下:

  • 导航触发
  • 失活组件:beforeRouteLeave
  • 全局:beforeEach
  • 激活组件:路由配置中beforeEnter
  • 解析异步组件
  • 激活组件:beforeRouteEnter
  • 全局:beforeResolve
  • 导航被确认
  • 全局:afterEach
  • 触发DOM更新
  • 激活组件:beforeRouteEnter中的next被调用,并将当前组件实例化对象作为参数传入回调函数

image.png

当配置了动态路由时,在/comp-a/1/comp-a/2互相切换时,由于组件被复用,所以不会触发组件的导航守卫,这时的导航守卫的触发顺序如下:

  • 导航触发
  • 全局: beforeEach
  • 组件:beforeRouteUpdate
  • 全局:beforeResolve
  • 导航被确认
  • 全局:afterEach
  • 触发DOM更新
const routes = [
  {
    path: "/comp-a/:id",
    name: "comp-a",
    props: true,
    component: compA,
    // 配置中的路由守卫
    beforeEnter: (to, from, next) => {
      console.log(to.name, ": beforeEnter");
      next();
    },
  }
]

image.png

测试源码路径:github.com/mkolp115977…