优化动态标签页注册逻辑

This commit is contained in:
jxxghp
2025-07-05 14:06:00 +08:00
parent 17cf640e23
commit 20dced021d
6 changed files with 51 additions and 21 deletions
+27 -2
View File
@@ -1,3 +1,5 @@
import type { ComputedRef, Ref } from 'vue'
// 动态标签页相关类型 // 动态标签页相关类型
interface DynamicHeaderTabButton { interface DynamicHeaderTabButton {
icon: string icon: string
@@ -33,12 +35,12 @@ export function useDynamicHeaderTab() {
// 注册动态标签页 // 注册动态标签页
const registerHeaderTab = (config: { const registerHeaderTab = (config: {
items: DynamicHeaderTabItem[] items: DynamicHeaderTabItem[] | ComputedRef<DynamicHeaderTabItem[]> | Ref<DynamicHeaderTabItem[]>
modelValue: Ref<string> modelValue: Ref<string>
appendButtons?: DynamicHeaderTabButton[] appendButtons?: DynamicHeaderTabButton[]
}) => { }) => {
const tabConfig: DynamicHeaderTabConfig = { const tabConfig: DynamicHeaderTabConfig = {
items: config.items, items: Array.isArray(config.items) ? config.items : config.items.value,
modelValue: config.modelValue.value, modelValue: config.modelValue.value,
appendButtons: config.appendButtons, appendButtons: config.appendButtons,
routePath: route.path, 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 = () => { const doRegister = () => {
// 确保路由路径是最新的 // 确保路由路径是最新的
tabConfig.routePath = route.path tabConfig.routePath = route.path
// 确保items是最新的
tabConfig.items = Array.isArray(config.items) ? config.items : config.items.value
if (registerDynamicHeaderTab) { if (registerDynamicHeaderTab) {
registerDynamicHeaderTab(tabConfig) registerDynamicHeaderTab(tabConfig)
+6 -12
View File
@@ -124,16 +124,13 @@ provide('unregisterDynamicHeaderTab', unregisterDynamicHeaderTab)
// 监听路由变化来清除动态标签页 // 监听路由变化来清除动态标签页
watch( watch(
() => route.path, () => route.path,
(newPath, oldPath) => { () => {
// 使用nextTick确保新页面的组件已经挂载完成 // 使用nextTick确保新页面的组件已经挂载完成
nextTick(() => { nextTick(() => {
// 延迟一小段时间,让新页面有机会注册标签页 // 如果当前标签页不属于新路由,则清除
setTimeout(() => { if (dynamicHeaderTab.value && dynamicHeaderTab.value.routePath !== route.path) {
// 如果当前标签页不属于新路由,则清除 dynamicHeaderTab.value = null
if (dynamicHeaderTab.value && dynamicHeaderTab.value.routePath !== route.path) { }
dynamicHeaderTab.value = null
}
}, 50) // 减少延迟时间,但仍然给新页面注册机会
}) })
}, },
{ immediate: false }, { immediate: false },
@@ -142,10 +139,7 @@ watch(
// 显示动态标签页 // 显示动态标签页
const showDynamicHeaderTab = computed(() => { const showDynamicHeaderTab = computed(() => {
return ( return (
dynamicHeaderTab.value && dynamicHeaderTab.value && dynamicHeaderTab.value.items.length > 0 && dynamicHeaderTab.value.routePath === route.path
dynamicHeaderTab.value.items.length > 0 &&
// 确保只在注册的路由路径下显示标签页
dynamicHeaderTab.value.routePath === route.path
) )
}) })
+4 -4
View File
@@ -128,16 +128,16 @@ onBeforeMount(async () => {
await loadOrderConfig() await loadOrderConfig()
await loadExtraDiscoverSources() await loadExtraDiscoverSources()
sortSubscribeOrder() sortSubscribeOrder()
})
onMounted(() => {
// 选中第一个标签页 // 选中第一个标签页
if (discoverTabs.value.length > 0) { if (discoverTabs.value.length > 0) {
activeTab.value = discoverTabs.value[0].mediaid_prefix activeTab.value = discoverTabs.value[0].mediaid_prefix
} }
})
onMounted(() => {
// 注册动态标签页 // 注册动态标签页
registerHeaderTab({ registerHeaderTab({
items: discoverTabItems.value, items: discoverTabItems, // 传递computed值,而不是.value
modelValue: activeTab, modelValue: activeTab,
appendButtons: [ appendButtons: [
{ {
+2 -2
View File
@@ -206,7 +206,7 @@ onMounted(async () => {
// 注册动态标签页 // 注册动态标签页
registerHeaderTab({ registerHeaderTab({
items: categoryItems.value, items: categoryItems,
modelValue: currentCategory, modelValue: currentCategory,
appendButtons: [ appendButtons: [
{ {
@@ -223,7 +223,7 @@ onMounted(async () => {
}) })
onActivated(async () => { onActivated(async () => {
loadExtraRecommendSources() await loadExtraRecommendSources()
}) })
</script> </script>
+6 -1
View File
@@ -6,6 +6,9 @@ import {
// @ts-ignore // @ts-ignore
} from 'virtual:__federation__' } from 'virtual:__federation__'
// 创建一个专用的AbortController,用于federationLoader请求
const federationController = new AbortController()
// 定义远程模块接口 // 定义远程模块接口
interface RemoteModule { interface RemoteModule {
id: string id: string
@@ -62,7 +65,9 @@ export async function loadRemoteComponent(id: string, componentName: string = 'P
*/ */
async function fetchRemoteModules(): Promise<RemoteModule[]> { async function fetchRemoteModules(): Promise<RemoteModule[]> {
try { 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) || [] return (response as any) || []
} catch (error) { } catch (error) {
console.error('获取远程模块列表失败:', error) console.error('获取远程模块列表失败:', error)
+6
View File
@@ -1,10 +1,16 @@
import api from '@/api' import api from '@/api'
// 创建一个专用的AbortController,用于globalSetting请求
const globalSettingController = new AbortController()
export async function fetchGlobalSettings() { export async function fetchGlobalSettings() {
try { try {
const result: { [key: string]: any } = await api.get('system/global', { const result: { [key: string]: any } = await api.get('system/global', {
params: { params: {
token: 'moviepilot', token: 'moviepilot',
}, },
// 手动设置signal,防止reqestOptimizer添加可中断的controller
signal: globalSettingController.signal,
}) })
return result.data || {} return result.data || {}
} catch (error) { } catch (error) {