mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 23:56:42 +08:00
优化动态标签页注册逻辑
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -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: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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,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)
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user