问题描述
由于我希望路由初始化完成后再挂载 APP 实例,所以在 main.ts
中有以下代码
// main.ts
console.log("execute 111");
// 路由初始化完成后挂载 APP 实例,使用了顶层 await 进行异步加载
await router.isReady();
console.log("execute 222");
app.mount("#app");
在开发环境环境下,运行开发服务器,打开浏览器控制台,execute 111
和 execute 222
都会打印,页面路由也能正常访问;但是打包部署后,生产环境下只有 execute 111
打印了,页面空白,而且控制台没有报错。
问题处理 - 方法一
控制台没有报错,那应该不会进入到 catch,我也尝试了用 try…catch… 包裹 await,在 catch 阶段输出,并没有输出错误,所以可以排除这种情况。接着我打开我的路由配置文件:
import { App } from "vue";
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
const constantRoutes: RouteRecordRaw[] = [
{
path: "/",
name: "home",
component: () => import("@/views/home/index.vue"),
},
{
path: "/:pathMatch(.*)",
name: "404",
component: () => import("@/views/error/404.vue"),
},
];
发现了问题所在,component: () => import("@/views/home/index.vue"),
的写法属于异步懒加载的方式,而 await router.isReady();
的写法属于顶层 await 的方式(它会阻塞资源获取)。这不就出现了死循环,前者说有访问者访问时我才加载,后者说我要拦住所有访问者,除非有访问者访问你了我才放开所有访问者,最后不就一直等下去了。所以我们可以改一下首页路由配置,让其变成直接加载的方式,其它页面继续保留懒加载不需要变动,修改如下:
// router/index.ts
import { App } from "vue";
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
import Home from "@/views/home/index.vue";
const constantRoutes: RouteRecordRaw[] = [
{
path: "/",
name: "home",
// - component: () => import("@/views/home/index.vue"),
component: Home, // +
},
{
path: "/:pathMatch(.*)",
name: "404",
component: () => import("@/views/error/404.vue"),
},
];
这样就保证了首页路由可以一开始就完成初始化操作,此时再打包部署,首页就可以加载出来了。
问题处理 - 方法二
如果我们不想变动 router/index.ts
文件的内容,就希望里面的路由是处于懒加载状态,也是可以的。我们知道了顶层 await 具有阻塞资源获取的特性,导致了资源无法加载,那么我们就不用顶层 await,用 .then()
去实现异步加载也是可以的,修改 main.ts
代码:
// main.ts
router
.isReady()
.then(() => {
app.mount("#app");
})
.catch((err) => {
console.log(err);
});
.then()
不会阻塞资源获取,此时再打包部署,首页也是可以加载出来的。