1、导航被触发
2、在失活的组件里调用 beforeRouteLeave 守卫
组件内守卫beforeRouteLeave
:在离开该组件之前,会先调用它(用于在离开组件前保存或清理一些状态)
import { onBeforeRouteLeave } from 'vue-router'onBeforeRouteLeave((to, from, next) => {console.log('to=', to)console.log('from=', from)* 如果需要,你可以基于条件阻止导航if (/* some condition */) {next(false) // 取消导航} else {next() // 允许导航}* 默认情况下,调用 next() 允许导航继续next(false)})
3、调用全局的 beforeEach 守卫
全局的前置守卫beforeEach
:它会在路由改变之前被调用,用于执行一些全局的权限检查、重定向等逻辑
4、在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)
组件内守卫beforeRouteUpdate
:当路由改变,但是该组件被复用时(例如,只是路由参数改变)
这个守卫,允许,你在组件复用时执行一些逻辑,比如更新DOM。
const userId = ref(null)const route = useRoute()setup() {onBeforeRouteUpdate((to, from, next) => {* 根据新的路由参数,来更新组件的数据userId.value = to.params.id // 假设,路由参数中有一个idnext()})// 初始化userId(可选,取决于你的具体需求)if (route.params.id) {userId.value = route.params.id}}
5、在路由配置里调用 beforeEnter
6、解析异步路由组件
7、在被激活的组件里调用 beforeRouteEnter
在进入目标路由的组件之前,会调用 beforeRouteEnter 守卫,
注意:
因为,这个守卫,在导航被确认之前调用,所以,此时的组件实例,还没有被创建,因此,你不能直接访问组件实例,但是,你可以通过 next 回调来访问组件实例。
setup() {const someData = ref(null)注意:'onBeforeRouteEnter' 不能在 'setup' 中直接使用,因此,我们需要将它作为一个单独的函数,定义在组件外部const beforeRouteEnterGuard = (to, from, next) => {* 这里没有组件实例,因为,组件还没有被创建,但是,你可以访问路由参数和查询console.log('在组件被创建之前,即将进入路由', to.path)* 可以在这里执行一些异步操作,比如:从服务器获取数据next(vm => {*通过 `vm` 访问组件实例})}* 在组件外部,定义 'onBeforeRouteEnter' 守卫onBeforeRouteEnter(beforeRouteEnterGuard)onMounted(() => { console.log('组件已挂载')})
}
8、调用全局的 beforeResolve 守卫(2.5+)
它在,所有组件内守卫
和 异步路由组件被解析之后,但在DOM更新之前被调用
(此时,DOM未更新,所以不能直接操作DOM),
意味着,在 beforeResolve 守卫中,可以进行那些依赖于异步解析的数据的操作,
import { createRouter, createWebHistory } from 'vue-router'const routes = [ {path: '/async',name: 'Async',component: () => import('./views/AsyncComponent.vue')}// ...]const router = createRouter({history: createWebHistory(),routes,})* 使用 beforeResolve 守卫router.beforeResolve(async (to, from, next) => {* 假设,我们需要根据路由的某些参数,来加载一些数据if (to.path === '/async') {try {* 异步获取一些数据const data = await fetchSomeData(to.query.id) * 假设,fetchSomeData是一个返回Promise的函数* 你可以将数据存储在:Vuex、localStorage、sessionStorageconsole.log('Loaded data for route=', data)* 确保导航继续next()} catch (error) {* 如果加载数据失败,可以重定向到错误页面,或执行其他逻辑console.error('Failed to load data:', error)next(false) // 中断导航// 或者你可以重定向到另一个路由// next('/error-page')}} else {* 对于其他路由,直接继续next()}})
9、导航被确认
此时,路由已经确定,并准备进行导航
10、调用全局的 afterEach 钩子
无论导航是否成功,都会调用 afterEach 钩子,
这个守卫不接受 next 函数,因为,它发生在所有导航守卫之后,此时路由跳转已经完成,
主要用于进行一些不需要等待导航完成的操作,如分析、记录等。
afterEach是全局后置守卫,它在路由跳转完成后被调用
import { createRouter, createWebHistory } from 'vue-router'const routes = [// 定义你的路由...]const router = createRouter({history: createWebHistory(),routes,})// 使用 afterEach 守卫router.afterEach((to, from) => {* 这里的逻辑,会在每次路由跳转完成后执行* 例如,我们可以记录一些导航信息console.log('Navigation Completed:', to.path)* 发送统计信息到服务器sendAjax({ fromPath: from.path, toPath: to.path })* 清除页面级别的临时数据// clearPageLevelData()* 其他需要在路由跳转后执行的操作....})
11、触发 DOM 更新
Vue 开始更新 DOM 以反映新的路由
12、调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入
如果,在 beforeRouteEnter 守卫中传递了一个回调函数给 next,
那么,在这个阶段会调用这个回调函数,
此时,组件实例
已经被创建,并会作为回调函数的参数
传入。