diff --git a/src/composables/useDynamicHeaderTab.ts b/src/composables/useDynamicHeaderTab.ts index 7d5c5763..708c68ea 100644 --- a/src/composables/useDynamicHeaderTab.ts +++ b/src/composables/useDynamicHeaderTab.ts @@ -1,3 +1,5 @@ +import type { ComputedRef, Ref } from 'vue' + // 动态标签页相关类型 interface DynamicHeaderTabButton { icon: string @@ -33,12 +35,12 @@ export function useDynamicHeaderTab() { // 注册动态标签页 const registerHeaderTab = (config: { - items: DynamicHeaderTabItem[] + items: DynamicHeaderTabItem[] | ComputedRef | Ref modelValue: Ref appendButtons?: DynamicHeaderTabButton[] }) => { const tabConfig: DynamicHeaderTabConfig = { - items: config.items, + items: Array.isArray(config.items) ? config.items : config.items.value, modelValue: config.modelValue.value, appendButtons: config.appendButtons, routePath: route.path, @@ -62,10 +64,33 @@ export function useDynamicHeaderTab() { } }) + // 如果items是computed或ref,也需要监听其变化 + if (!Array.isArray(config.items)) { + watch( + config.items, + newItems => { + tabConfig.items = newItems + // 重新注册以更新items + if (registerDynamicHeaderTab) { + registerDynamicHeaderTab(tabConfig) + } else if (typeof window !== 'undefined') { + // 使用全局方法作为备用 + const globalRegister = (window as any).__VUE_INJECT_DYNAMIC_HEADER_TAB__ + if (globalRegister) { + globalRegister(tabConfig) + } + } + }, + { deep: true }, + ) + } + // 注册函数 const doRegister = () => { // 确保路由路径是最新的 tabConfig.routePath = route.path + // 确保items是最新的 + tabConfig.items = Array.isArray(config.items) ? config.items : config.items.value if (registerDynamicHeaderTab) { registerDynamicHeaderTab(tabConfig) diff --git a/src/layouts/components/DefaultLayout.vue b/src/layouts/components/DefaultLayout.vue index ee088570..cd080ae0 100644 --- a/src/layouts/components/DefaultLayout.vue +++ b/src/layouts/components/DefaultLayout.vue @@ -124,16 +124,13 @@ provide('unregisterDynamicHeaderTab', unregisterDynamicHeaderTab) // 监听路由变化来清除动态标签页 watch( () => route.path, - (newPath, oldPath) => { + () => { // 使用nextTick确保新页面的组件已经挂载完成 nextTick(() => { - // 延迟一小段时间,让新页面有机会注册标签页 - setTimeout(() => { - // 如果当前标签页不属于新路由,则清除 - if (dynamicHeaderTab.value && dynamicHeaderTab.value.routePath !== route.path) { - dynamicHeaderTab.value = null - } - }, 50) // 减少延迟时间,但仍然给新页面注册机会 + // 如果当前标签页不属于新路由,则清除 + if (dynamicHeaderTab.value && dynamicHeaderTab.value.routePath !== route.path) { + dynamicHeaderTab.value = null + } }) }, { immediate: false }, @@ -142,10 +139,7 @@ watch( // 显示动态标签页 const showDynamicHeaderTab = computed(() => { return ( - dynamicHeaderTab.value && - dynamicHeaderTab.value.items.length > 0 && - // 确保只在注册的路由路径下显示标签页 - dynamicHeaderTab.value.routePath === route.path + dynamicHeaderTab.value && dynamicHeaderTab.value.items.length > 0 && dynamicHeaderTab.value.routePath === route.path ) }) diff --git a/src/pages/discover.vue b/src/pages/discover.vue index 67ca4016..1e337383 100644 --- a/src/pages/discover.vue +++ b/src/pages/discover.vue @@ -128,16 +128,16 @@ onBeforeMount(async () => { await loadOrderConfig() await loadExtraDiscoverSources() sortSubscribeOrder() +}) + +onMounted(() => { // 选中第一个标签页 if (discoverTabs.value.length > 0) { activeTab.value = discoverTabs.value[0].mediaid_prefix } -}) - -onMounted(() => { // 注册动态标签页 registerHeaderTab({ - items: discoverTabItems.value, + items: discoverTabItems, // 传递computed值,而不是.value modelValue: activeTab, appendButtons: [ { diff --git a/src/pages/recommend.vue b/src/pages/recommend.vue index d7543014..c1927950 100644 --- a/src/pages/recommend.vue +++ b/src/pages/recommend.vue @@ -206,7 +206,7 @@ onMounted(async () => { // 注册动态标签页 registerHeaderTab({ - items: categoryItems.value, + items: categoryItems, modelValue: currentCategory, appendButtons: [ { @@ -223,7 +223,7 @@ onMounted(async () => { }) onActivated(async () => { - loadExtraRecommendSources() + await loadExtraRecommendSources() }) diff --git a/src/utils/federationLoader.ts b/src/utils/federationLoader.ts index 461d9766..bbf0293c 100644 --- a/src/utils/federationLoader.ts +++ b/src/utils/federationLoader.ts @@ -6,6 +6,9 @@ import { // @ts-ignore } from 'virtual:__federation__' +// 创建一个专用的AbortController,用于federationLoader请求 +const federationController = new AbortController() + // 定义远程模块接口 interface RemoteModule { id: string @@ -62,7 +65,9 @@ export async function loadRemoteComponent(id: string, componentName: string = 'P */ async function fetchRemoteModules(): Promise { try { - const response = await api.get('plugin/remotes?token=moviepilot') + const response = await api.get('plugin/remotes?token=moviepilot', { + signal: federationController.signal, + }) return (response as any) || [] } catch (error) { console.error('获取远程模块列表失败:', error) diff --git a/src/utils/globalSetting.ts b/src/utils/globalSetting.ts index 409fc465..f1586b02 100644 --- a/src/utils/globalSetting.ts +++ b/src/utils/globalSetting.ts @@ -1,10 +1,16 @@ import api from '@/api' + +// 创建一个专用的AbortController,用于globalSetting请求 +const globalSettingController = new AbortController() + export async function fetchGlobalSettings() { try { const result: { [key: string]: any } = await api.get('system/global', { params: { token: 'moviepilot', }, + // 手动设置signal,防止reqestOptimizer添加可中断的controller + signal: globalSettingController.signal, }) return result.data || {} } catch (error) {