[Keep-alive] 手动控制已缓存组件的销毁

2025-09-26

我在尝试实现共享相同组件的选项卡时遇到了同样的问题。当用户关闭选项卡时,我希望只删除该特定实例的缓存。以下是我认为在 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')))
})

最后,生成一个计算属性作为includeKeepAlive 的 prop。

const keepAliveIncludes = computed(() => tabs.map((tab) => tab.page.name))

现在将它绑定到includeKeepAlive 的 prop 上并享受魔力:

<KeepAlive :include="keepAliveIncludes">
  <component :is="tab.page">
</KeepAlive>

在上面的示例中,当你从tabs数组中删除一个项目(用户关闭选项卡)时,该特定实例的缓存也将被删除,而使用相同组件的其余实例将保留并保持其状态。你可以在 Vue DevTools 中确认这一点。

NEXT
一次 XML 上传导致域名被封的经历复盘