From 3c90c3ccfe5d750ebad9182bc92f1a1f839d8961 Mon Sep 17 00:00:00 2001 From: dap <15891557205@163.com> Date: Tue, 13 May 2025 21:15:58 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E8=B7=AF=E7=94=B1=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E4=B8=8E=E7=BB=84=E4=BB=B6=E5=90=8D=E7=A7=B0=E4=BF=9D?= =?UTF-8?q?=E6=8C=81=E4=B8=80=E8=87=B4=EF=BC=8C=E8=A7=A3=E5=86=B3keepAlive?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/router/elegant/helper.ts | 49 ++++++++++++++++++++++++++++++++ src/router/elegant/transform.ts | 8 ++++-- src/store/modules/route/index.ts | 4 +-- 3 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 src/router/elegant/helper.ts diff --git a/src/router/elegant/helper.ts b/src/router/elegant/helper.ts new file mode 100644 index 00000000..023a4d66 --- /dev/null +++ b/src/router/elegant/helper.ts @@ -0,0 +1,49 @@ +/* eslint-disable no-console */ +/** 后台返回的路由动态生成name 解决缓存问题 感谢 @fourteendp 详见 https://github.com/vbenjs/vue-vben-admin/issues/3927 */ +import type { Component } from 'vue'; +import { defineComponent, h } from 'vue'; + +interface Options { + name?: string; +} + +export type RouteComponentLoader = () => Promise; + +/** + * 作用相当于给组件包了一层 & 设置name 解决keepAlive问题 + * + * @param loader 导入的路由 + * @param options options + * @returns components + */ +export function createCustomNameComponent( + loader: RouteComponentLoader, + options: Options = {} +): () => Promise { + const { name } = options; + let component: Component | null = null; + + const load = async () => { + try { + const { default: loadedComponent } = await loader(); + component = loadedComponent; + } catch (error) { + console.error(`Cannot resolve component ${name}, error:`, error); + } + }; + + return async () => { + if (!component) { + await load(); + } + + return Promise.resolve( + defineComponent({ + name, + render() { + return h(component as Component); + } + }) + ); + }; +} diff --git a/src/router/elegant/transform.ts b/src/router/elegant/transform.ts index 797392e0..e37dfbc4 100644 --- a/src/router/elegant/transform.ts +++ b/src/router/elegant/transform.ts @@ -6,6 +6,7 @@ import type { RouteRecordRaw, RouteComponent } from 'vue-router'; import type { ElegantConstRoute } from '@elegant-router/vue'; import type { RouteMap, RouteKey, RoutePath } from '@elegant-router/types'; +import { createCustomNameComponent, RouteComponentLoader } from './helper'; /** * transform elegant const routes to vue routes @@ -125,8 +126,11 @@ function transformElegantRouteToVueRoute( if (isView(component)) { const viewName = getViewName(component); - - vueRoute.component = views[viewName]; + // 给组件设置name 与route.name一致 + vueRoute.component = createCustomNameComponent(views[viewName] as RouteComponentLoader, + { name: route.name }); + // 路由名称与组件名称保持一致,解决keepAlive问题 + vueRoute.name = route.name; } } diff --git a/src/store/modules/route/index.ts b/src/store/modules/route/index.ts index 0755659e..84dfac09 100644 --- a/src/store/modules/route/index.ts +++ b/src/store/modules/route/index.ts @@ -113,8 +113,8 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => { // @ts-expect-error no hidden field route.meta.hideInMenu = Boolean(route.hidden) || false; - - route.meta.keepAlive = Boolean(route.meta.noCache) || false; + // 是否需要keepAlive + route.meta.keepAlive = !route.meta.noCache || false; if (route.component !== 'layout.base') { route.component = parent ? `view.${route.component}` : `layout.base$view.${route.component}`;