diff --git a/examples/blog/docs/notes/前端/vue-router-mount-timing.md b/examples/blog/docs/notes/前端/vue-router-mount-timing.md new file mode 100644 index 00000000..11b4d499 --- /dev/null +++ b/examples/blog/docs/notes/前端/vue-router-mount-timing.md @@ -0,0 +1,162 @@ +--- +title: Vue App 挂载与 Router beforeEach 时序关系 +createTime: 2026/04/12 12:05:23 +tags: + - Vue + - Vue Router +--- + +## 问题背景 + +在使用 Vue 3 + Vue Router 开发应用时,遇到了一个**时序问题**: + +::: warning 现象 +`App.vue` 中的 `onMounted` 钩子**先于** `router.beforeEach` 路由守卫执行,导致在路由守卫中进行的异步权限校验还未完成时,页面逻辑已经开始执行。 +::: + +## 问题复现 + +```ts title="main.ts" +import { createApp } from "vue"; +import App from "./App.vue"; +import router from "./router"; + +const app = createApp(App); + +app.use(router); // 安装路由 +app.mount("#app"); // 挂载应用 +``` + +```ts title="router/index.ts" +router.beforeEach(async (to, from) => { + // 异步请求:获取用户权限 + await fetchUserPermission(); // 假设耗时 500ms + // ... ... +}); +``` + +```vue title="App.vue" + +``` + +## 问题分析 + +按照 Vue Router 文档,标准执行顺序应该是: + +```text +app.use(router) → app.mount() → beforeEach → 组件挂载 +``` + +但在 `beforeEach` 中加入异步请求后,执行顺序变成了: + +```text +app.use(router) → app.mount() → App.vue mounted → beforeEach 完成 +``` + +`beforeEach` 虽然是异步解析,但它**不会阻塞**根组件 `App.vue` 的同步挂载流程。 +`beforeEach` 守卫**只阻塞路由匹配的组件创建**,如果路由组件直接配置为 `App.vue` ,`
`的挂载并不会被阻塞。根本原因在于根组件 `App.vue` 在 `app.mount()` 时已经**同步创建和挂载** + +## 解决方案 + +把业务逻辑拆分,`App.vue`只作为静态挂载点存在,实际业务逻辑用`