diff --git a/apps/jingrow/frontend/src/app/router/detailPage.ts b/apps/jingrow/frontend/src/app/router/detailPage.ts new file mode 100644 index 0000000..23ba4bf --- /dev/null +++ b/apps/jingrow/frontend/src/app/router/detailPage.ts @@ -0,0 +1,50 @@ +import { defineComponent, onMounted, shallowRef, markRaw, computed, watch, h } from 'vue' +import { useRoute, useRouter } from 'vue-router' +import { usePageTypeSlug } from '@/shared/utils/slug' +import { resolvePagetypeDetailOverride } from '@/core/registry/pagetypeOverride' +import GenericDetailPage from '@/core/pagetype/GenericDetailPage.vue' + +/** + * 详情页路由分发器:决定使用覆盖组件还是默认组件 + * 位置:app/router/detailPage.ts - 与路由配置在同一目录,职责清晰 + */ +export default defineComponent({ + name: 'DetailPage', + setup() { + const route = useRoute() + const router = useRouter() + const { pagetypeSlug } = usePageTypeSlug(route) + const overrideComponent = shallowRef(null) + + // 为覆盖组件准备 context(可选,覆盖组件可独立工作) + const context = computed(() => ({ + route, + router, + pagetypeSlug: pagetypeSlug.value, + entity: route.params.entity as string, + id: route.params.id as string + })) + + onMounted(async () => { + // 查找详情页覆盖组件 + const detailComp = await resolvePagetypeDetailOverride(pagetypeSlug.value) + overrideComponent.value = detailComp ? markRaw(detailComp) : null + }) + + // 监听路由参数变化,当 entity 或 id 变化时重新加载覆盖组件 + watch(() => [route.params.entity, route.params.id], async ([newEntity, newId], [oldEntity, oldId]) => { + if (newEntity !== oldEntity || newId !== oldId) { + const detailComp = await resolvePagetypeDetailOverride(String(newEntity || pagetypeSlug.value)) + overrideComponent.value = detailComp ? markRaw(detailComp) : null + } + }, { immediate: false }) + + return () => { + if (overrideComponent.value) { + return h(overrideComponent.value, { context: context.value }) + } + return h(GenericDetailPage) + } + } +}) + diff --git a/apps/jingrow/frontend/src/app/router/index.ts b/apps/jingrow/frontend/src/app/router/index.ts index b369035..f8ee8f9 100644 --- a/apps/jingrow/frontend/src/app/router/index.ts +++ b/apps/jingrow/frontend/src/app/router/index.ts @@ -76,23 +76,23 @@ const router = createRouter({ { path: 'app/:entity', name: 'PageTypeList', - component: () => import('../../core/pagetype/ListPage.vue') + component: () => import('./listPage') }, { path: 'app/:entity/:id', name: 'PageTypeDetail', - component: () => import('../../core/pagetype/DetailPage.vue') + component: () => import('./detailPage') }, // 保持向后兼容 { path: 'page/:entity', name: 'PageTypeListLegacy', - component: () => import('../../core/pagetype/ListPage.vue') + component: () => import('./listPage') }, { path: 'page/:entity/:id', name: 'PageTypeDetailLegacy', - component: () => import('../../core/pagetype/DetailPage.vue') + component: () => import('./detailPage') }, { path: 'settings/menu', diff --git a/apps/jingrow/frontend/src/app/router/listPage.ts b/apps/jingrow/frontend/src/app/router/listPage.ts new file mode 100644 index 0000000..30a3916 --- /dev/null +++ b/apps/jingrow/frontend/src/app/router/listPage.ts @@ -0,0 +1,47 @@ +import { defineComponent, onMounted, shallowRef, markRaw, computed, watch, h } from 'vue' +import { useRoute } from 'vue-router' +import { usePageTypeSlug } from '@/shared/utils/slug' +import { resolvePagetypeListOverride } from '@/core/registry/pagetypeOverride' +import GenericListPage from '@/core/pagetype/GenericListPage.vue' + +/** + * 列表页路由分发器:决定使用覆盖组件还是默认组件 + * 位置:app/router/listPage.ts - 与路由配置在同一目录,职责清晰 + */ +export default defineComponent({ + name: 'ListPage', + setup() { + const route = useRoute() + const { pagetypeSlug } = usePageTypeSlug(route) + const overrideComponent = shallowRef(null) + + // 为覆盖组件准备 context(可选,覆盖组件可独立工作) + const context = computed(() => ({ + route, + pagetypeSlug: pagetypeSlug.value, + entity: route.params.entity as string + })) + + onMounted(async () => { + // 查找列表页覆盖组件 + const listComp = await resolvePagetypeListOverride(pagetypeSlug.value) + overrideComponent.value = listComp ? markRaw(listComp) : null + }) + + // 监听路由参数变化,当 entity 变化时重新加载覆盖组件 + watch(() => route.params.entity, async (newEntity, oldEntity) => { + if (newEntity !== oldEntity) { + const listComp = await resolvePagetypeListOverride(String(newEntity)) + overrideComponent.value = listComp ? markRaw(listComp) : null + } + }) + + return () => { + if (overrideComponent.value) { + return h(overrideComponent.value, { context: context.value }) + } + return h(GenericListPage) + } + } +}) + diff --git a/apps/jingrow/frontend/src/core/pagetype/DetailPage.vue b/apps/jingrow/frontend/src/core/pagetype/DetailPage.vue deleted file mode 100644 index 4e28ae4..0000000 --- a/apps/jingrow/frontend/src/core/pagetype/DetailPage.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - diff --git a/apps/jingrow/frontend/src/core/pagetype/ListPage.vue b/apps/jingrow/frontend/src/core/pagetype/ListPage.vue deleted file mode 100644 index 52f6876..0000000 --- a/apps/jingrow/frontend/src/core/pagetype/ListPage.vue +++ /dev/null @@ -1,48 +0,0 @@ - - - - - -