我在尝试实现共享相同组件的选项卡时遇到了同样的问题。当用户关闭选项卡时,我希望只删除该特定实例的缓存。以下是我认为在 Vue3 中解决这个问题最优雅的方法。
由于 KeepAlive只接受组件名称的include
/ exclude
,因此解决这个问题最明显的方案之一就是将共享组件包装到 HOC 中,为每个实例赋予唯一的name
。我的实现如下:
const createUniqueComponent = (component) => {
return markRaw(
defineComponent({
name: 'DynamicComp_' + Math.random().toString(36).slice(2, 9),
components: {
uc: component
},
render() {
return h(component, null, this.$slots);
}
})
);
};
然后,在需要创建组件实例的地方使用它,例如在路由器或存储中。就我而言,我动态导入了组件,因此代码如下所示:
tabs.push({
...
page: createUniqueComponent(defineAsyncComponent(() => import('@/views/SomeTabPage')))
})
最后,生成一个计算属性作为include
KeepAlive 的 prop。
const keepAliveIncludes = computed(() => tabs.map((tab) => tab.page.name))
现在将它绑定到include
KeepAlive 的 prop 上并享受魔力:
<KeepAlive :include="keepAliveIncludes">
<component :is="tab.page">
</KeepAlive>
在上面的示例中,当你从tabs
数组中删除一个项目(用户关闭选项卡)时,该特定实例的缓存也将被删除,而使用相同组件的其余实例将保留并保持其状态。你可以在 Vue DevTools 中确认这一点。