最近在开发 Vue3 项目的时候,因为业务需要,存在两个页面布局、逻辑等差不多的页面,本着偷懒?,给同一个路由组件注册了不同的 path,通过传递的路径参数,执行不同的逻辑以获取对应的数据。
此时,路由组件包裹了一个 KeepAlive,让他们保持不被销毁。
下面是路由注册情况:
const routes = [
{
name: RouteName.HOME,
path: "/",
component: () => import("./fragments/Common.vue")
},
{
name: RouteName.CATEGORY,
path: "/c/:id/:page",
component: () => import("./fragments/Common.vue")
}
];
这两个 path 对应的都是同一个路由组件,由于 KeepAlive,当从一个 path 跳转到 Common.vue 之后,再从另一个 path 跳转到同一个 Common.vue(⚠️注意,浏览器不能刷新的情况下),第二次再进入这个 Common.vue 它还是保持上一次的状态。存在一个谁先谁后的问题(也就是 mounted),除非强制性刷新浏览器。
下面是 Common.vue setup
函数中的代码,fetchData
是获取数据的一个异步函数。根据传递的参数而执行不同的 API:
if (categoryId) {
fetchData(categoryId, categoryPage, true);
} else {
fetchData(false, 1, false);
}
来看看组件的周期到底是怎么样的?
这是第一次进入的 path:
这是第二次进入的 path:
下面是进入不同 path 而是同一个路由组件的生命周期函数触发情况:
Common.vue 路由组件发生了很多次 activated 和 deactived。唯独 mounted 只触发了一次,也就是第一次进入这个路由组件时触发的。
去掉 KeepAlive 是否可以解决问题呢?但,破坏了我最开始的业务要求,即缓存组件状态,而不希望切换时销毁路由组件。
不去掉 KeepAlive ?使用 KeepAlive 的周期函数:activated 或 deactived 来执行不同的 API。具体说明请查看官方文档?:KeepAlive 缓存实例的生命周期。