前言
vue-router
完整的导航解析流程官方给出来的是以下的方式:
- 导航被触发。
- 在失活的组件里调用
beforeRouteLeave
守卫。 - 调用全局的
beforeEach
守卫。 - 在重用的组件里调用
beforeRouteUpdate
守卫(2.2+)。 - 在路由配置里调用
beforeEnter
。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter
。 - 调用全局的
beforeResolve
守卫(2.5+)。 - 导航被确认。
- 调用全局的
afterEach
钩子。 - 触发 DOM 更新。
- 调用
beforeRouteEnter
守卫中传给next
的回调函数,创建好的组件实例会作为回调函数的参数传入。
但是你实际上真的是理解了上述的流程吗?
实际的解析流程
其实它上述的流程是存在偏差的, 就是在判断组件是否失活这里, 可以通过下图的流程来判断。
理解组件失活
vue中组件失活, 就相当于整个组件不在页面中展示了,需要搭配vue中的KeepAlive
内置组件实现,这里就不过多解释,需要的自己去看官方文档, 借助它自己的两个API(onActivated
、onDeactivated
)理解。
未失活的组件路由导航解析流程
未失活的组件路由更新, 一般指的是主路由未发生变化,只是增加了路由携带的参数。例如:/home => /home?name='zhangsan'&age="18"
。
准备一个home页面, 配置一个点击事件。
// router.js中的三个全局路由导航
router.beforeEach((to, from, next) => {
console.log(to,'<==================>', from)
console.log("全局前置守卫")
next()
})
router.beforeResolve((to, from, next) => {
// console.log(to,'<==================>', from)
console.log("全局解析守卫")
next()
})
router.afterEach((to, from) => {
// console.log(to,'<==================>', from)
console.log("全局后置钩子")
})
// 路由专享导航-beforeEnter
{
path: "/",
name: "Home",
component: Home,
alias: ["/home", '/home/:id'],
beforeEnter: () => {
console.log("路由专项钩子")
}
},
// Home-page
<template>
<div>
<h1>Home</h1>
<router-link to="/about">前往About页面</router-link>
<br/>
<button @click="goToHome">未失活路由</button>
<!-- <router-view></router-view> -->
</div>
</template>
<script setup lang="ts">
import {useRouter, onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router';
const router = useRouter()
const goToHome = () => {
router.push({
path: '/home',
query: {
name: 'home',
age: 18
}
})
}
onBeforeRouteLeave((to, from) => {
console.log('离开时调用')
})
onBeforeRouteUpdate((to, from) => {
console.log('复用时调用')
})
</script>
整体的解析:
- 触发路由导航
- 判断是否组件失活,未失活就直接执行全局路由
beforeEach
; - 调用
beforeRouteUpdate
更新路由导航; - 调用全局钩子
beforeResolve
进行解析; - 调用全局后置钩子
afterEach
; - 触发 DOM 更新。
失活的组件路由导航解析流程
失活的组件,代码如上述的一致,当跳转到about page
页面的路由导航卫士触发情况。
整体的解析流程:
- 触发路由导航;
- 判断组件是否失活,是则调用
beforeRouteLeave
, 这个就能获取到home路由的组件实例,和即将去的路由信息; - 调用全局守卫
beforeEach
- 调用路由配置的专享钩子
beforeEnter
- 解析异步路由组件
- 在新的组件中调用
beforeRouteEnter
, 需要注意,这里是不能拿到新组件实例的 - 调用全局的
beforeResolve
- 导航被确认
- 调用全局的后置钩子
afterEach
- 触发 DOM 更新;
- 这个时候就需要将创建好的组件实例则作为
beforeRouteEnter
的next方法参数传入执行。
结语
这里就是关于vue-router的路由导航卫士实际解析流程的情况,很多时候还是需要自己去敲代码去实现查看情况, 光看文档和八股文是不能很好的去理解这些知识。