From e657a507e3b85d65efb05bf156efef6d7c423781 Mon Sep 17 00:00:00 2001 From: dap <15891557205@163.com> Date: Sun, 30 Jun 2024 10:50:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8A=A8=E6=80=81=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=AE=9E=E4=BE=8B=E6=97=B6,=20=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E8=B7=AF=E7=94=B1name=E4=B8=BA=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=20=E8=A7=A3=E5=86=B3=E7=BC=93=E5=AD=98=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/modules/permission.ts | 8 +++-- src/utils/createCustomNameComponent.tsx | 39 +++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 src/utils/createCustomNameComponent.tsx diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts index 8bab2d8..2e719ba 100644 --- a/src/store/modules/permission.ts +++ b/src/store/modules/permission.ts @@ -9,6 +9,8 @@ import Layout from '@/layout/index.vue'; import ParentView from '@/components/ParentView/index.vue'; import InnerLink from '@/layout/components/InnerLink/index.vue'; +import { createCustomNameComponent } from '@/utils/createCustomNameComponent'; + // 匹配views里面所有的.vue文件 const modules = import.meta.glob('./../../views/**/*.vue'); export const usePermissionStore = defineStore('permission', () => { @@ -82,7 +84,7 @@ export const usePermissionStore = defineStore('permission', () => { } else if (route.component?.toString() === 'InnerLink') { route.component = InnerLink; } else { - route.component = loadView(route.component); + route.component = loadView(route.component, route.name as string); } if (route.children != null && route.children && route.children.length) { route.children = filterAsyncRouter(route.children, route, type); @@ -153,12 +155,12 @@ export const filterDynamicRoutes = (routes: RouteRecordRaw[]) => { return res; }; -export const loadView = (view: any) => { +export const loadView = (view: any, name: string) => { let res; for (const path in modules) { const dir = path.split('views/')[1].split('.vue')[0]; if (dir === view) { - res = () => modules[path](); + res = createCustomNameComponent(modules[path], { name }); } } return res; diff --git a/src/utils/createCustomNameComponent.tsx b/src/utils/createCustomNameComponent.tsx new file mode 100644 index 0000000..daf5866 --- /dev/null +++ b/src/utils/createCustomNameComponent.tsx @@ -0,0 +1,39 @@ +/** + * 后台返回的路由动态生成name 解决缓存问题 + * 感谢 @fourteendp + * 详见 https://github.com/vbenjs/vue-vben-admin/issues/3927 + */ +import { Component, defineComponent, h } from 'vue'; + +interface Options { + name?: string; +} + +export function createCustomNameComponent(loader: () => Promise, 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); + } + }) + ); + }; +}