From 28f1c0718b57e3dff7fee94ab7dbbf2effee9b81 Mon Sep 17 00:00:00 2001 From: HavocZ Date: Mon, 28 Aug 2023 17:34:28 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E4=B8=80=E7=A7=8D=20?= =?UTF-8?q?keep-alive=20=E7=BC=93=E5=AD=98=E6=96=B9=E6=A1=88=20(#119)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layout/components/comp-consumer.ts | 56 ++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/layout/components/comp-consumer.ts diff --git a/src/layout/components/comp-consumer.ts b/src/layout/components/comp-consumer.ts new file mode 100644 index 0000000..60d2438 --- /dev/null +++ b/src/layout/components/comp-consumer.ts @@ -0,0 +1,56 @@ +import { useTagsViewStore } from "@/store/modules/tags-view" +import type { VNode } from "vue" +import { h } from "vue" +import { KeepAlive, cloneVNode, createVNode, defineComponent } from "vue" +import { useRoute } from "vue-router" +interface CompConsumerProps { + component?: VNode +} +const compMap = new Map() +export const CompConsumer = defineComponent( + (props: CompConsumerProps) => { + const tagsViewStore = useTagsViewStore() + const route = useRoute() + return () => { + const component = props.component + // 判断当前是否包含name,如果不包含name,那就直接处理掉name + if (!route.name) return component + // 获取当前组件的name + const compName = (component?.type as any)?.name + const routeName = route.name as string + let Comp: VNode + if (compMap.has(routeName)) { + // @ts-expect-error this is Node + Comp = compMap.get(routeName) + } else { + const node = cloneVNode(component!) + if (compName && compName === routeName) + // @ts-expect-error this is obj + node.type.name = `__${compName}__` + "CUSTOM_NAME" + // @ts-expect-error this is VNode + // eslint-disable-next-line vue/one-component-per-file + Comp = defineComponent({ + name: routeName, + setup() { + return () => node + } + }) + compMap.set(routeName, Comp) + } + return createVNode( + KeepAlive, + { + include: tagsViewStore.cachedViews + }, + { + default: () => h(Comp) + } + ) + } + // eslint-disable-next-line vue/one-component-per-file + }, + { + name: "CompConsumer", + props: ["component"] + } +)