mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-05-27 03:09:45 +08:00
增强远程组件注册机制,添加动态注册和获取功能,更新相关文档以指导插件开发者。调整多个组件以支持新注册逻辑。
This commit is contained in:
@@ -7,7 +7,12 @@ import { useToast } from 'vue-toast-notification'
|
||||
import FormRender from '../render/FormRender.vue'
|
||||
import ProgressDialog from '../dialog/ProgressDialog.vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { loadRemoteComponent, clearRemoteComponentCache } from '@/utils/remoteFederationLoader'
|
||||
import {
|
||||
loadRemoteComponent,
|
||||
clearRemoteComponentCache,
|
||||
registerRemoteComponent,
|
||||
getRemoteComponent,
|
||||
} from '@/utils/remoteFederationLoader'
|
||||
|
||||
// 国际化
|
||||
const { t } = useI18n()
|
||||
@@ -52,6 +57,14 @@ const vueComponentUrl = ref<string | null>(null)
|
||||
// Vue 模式:动态加载的组件
|
||||
const dynamicComponent = computed(() => {
|
||||
if (renderMode.value === 'vue' && vueComponentUrl.value) {
|
||||
// 检查是否已经注册,如果没有则进行注册
|
||||
const remoteInfo = props.plugin?.id ? getRemoteComponent(props.plugin.id) : null
|
||||
if (!remoteInfo && props.plugin?.id) {
|
||||
// 动态注册远程组件
|
||||
registerRemoteComponent(props.plugin.id, vueComponentUrl.value)
|
||||
}
|
||||
|
||||
// 加载远程组件
|
||||
return loadRemoteComponent(vueComponentUrl.value, {
|
||||
onError: error => {
|
||||
console.error(`加载插件组件失败: ${vueComponentUrl.value}`, error)
|
||||
|
||||
@@ -4,7 +4,12 @@ import type { Plugin } from '@/api/types'
|
||||
import PageRender from '@/components/render/PageRender.vue'
|
||||
import api from '@/api'
|
||||
import { useToast } from 'vue-toast-notification'
|
||||
import { loadRemoteComponent, clearRemoteComponentCache } from '@/utils/remoteFederationLoader'
|
||||
import {
|
||||
loadRemoteComponent,
|
||||
clearRemoteComponentCache,
|
||||
registerRemoteComponent,
|
||||
getRemoteComponent,
|
||||
} from '@/utils/remoteFederationLoader'
|
||||
|
||||
// 输入参数
|
||||
const props = defineProps({
|
||||
@@ -39,6 +44,14 @@ let pluginPageItems = ref([])
|
||||
// Vue 模式:动态加载的组件
|
||||
const dynamicComponent = computed(() => {
|
||||
if (renderMode.value === 'vue' && vueComponentUrl.value) {
|
||||
// 检查是否已经注册,如果没有则进行注册
|
||||
const remoteInfo = props.plugin?.id ? getRemoteComponent(props.plugin.id) : null
|
||||
if (!remoteInfo && props.plugin?.id) {
|
||||
// 动态注册远程组件
|
||||
registerRemoteComponent(props.plugin.id, vueComponentUrl.value)
|
||||
}
|
||||
|
||||
// 加载远程组件
|
||||
return loadRemoteComponent(vueComponentUrl.value, {
|
||||
onError: error => {
|
||||
console.error(`加载插件组件失败: ${vueComponentUrl.value}`, error)
|
||||
|
||||
@@ -12,8 +12,12 @@ import MediaServerLibrary from '@/views/dashboard/MediaServerLibrary.vue'
|
||||
import MediaServerPlaying from '@/views/dashboard/MediaServerPlaying.vue'
|
||||
import DashboardRender from '@/components/render/DashboardRender.vue'
|
||||
import { isNullOrEmptyObject } from '@/@core/utils'
|
||||
import api from '@/api'
|
||||
import { loadRemoteComponent, clearRemoteComponentCache } from '@/utils/remoteFederationLoader'
|
||||
import {
|
||||
loadRemoteComponent,
|
||||
clearRemoteComponentCache,
|
||||
registerRemoteComponent,
|
||||
getRemoteComponent,
|
||||
} from '@/utils/remoteFederationLoader'
|
||||
|
||||
// 输入参数
|
||||
const props = defineProps({
|
||||
@@ -37,6 +41,16 @@ const pluginRenderMode = computed(() => props.config?.render_mode || 'vuetify')
|
||||
const dynamicPluginComponent = computed(() => {
|
||||
// 确保 config 存在并且 component_url 也存在
|
||||
if (pluginRenderMode.value === 'vue' && props.config?.component_url) {
|
||||
// 如果有插件ID,尝试注册远程组件
|
||||
if (props.config.id) {
|
||||
const remoteInfo = getRemoteComponent(props.config.id)
|
||||
if (!remoteInfo) {
|
||||
// 动态注册远程组件
|
||||
registerRemoteComponent(props.config.id, props.config.component_url)
|
||||
}
|
||||
}
|
||||
|
||||
// 加载远程组件
|
||||
return loadRemoteComponent(props.config.component_url, {
|
||||
onError: error => {
|
||||
console.error(`加载插件组件失败: ${props.config?.component_url}`, error)
|
||||
|
||||
@@ -16,6 +16,51 @@ interface RemoteModuleState {
|
||||
// 已加载组件的缓存
|
||||
const loadedRemotes: Record<string, RemoteModuleState> = {}
|
||||
|
||||
// 动态注册的远程组件映射
|
||||
interface RemotePluginInfo {
|
||||
url: string
|
||||
pluginId: string
|
||||
moduleName: string
|
||||
}
|
||||
|
||||
// 已注册的远程模块
|
||||
const registeredRemotes: Record<string, RemotePluginInfo> = {}
|
||||
|
||||
/**
|
||||
* 动态注册远程组件
|
||||
* @param pluginId 插件ID
|
||||
* @param remoteUrl 远程组件URL
|
||||
* @returns 注册成功返回true,否则返回false
|
||||
*/
|
||||
export async function registerRemoteComponent(pluginId: string, remoteUrl: string): Promise<boolean> {
|
||||
try {
|
||||
// 生成远程模块名称(使用插件ID作为标识)
|
||||
const moduleName = `plugin_${pluginId.replace(/[^a-zA-Z0-9_]/g, '_')}`
|
||||
|
||||
// 注册到映射表中
|
||||
registeredRemotes[pluginId] = {
|
||||
url: remoteUrl,
|
||||
pluginId,
|
||||
moduleName,
|
||||
}
|
||||
|
||||
console.log(`已注册远程组件: ${pluginId} -> ${moduleName} (${remoteUrl})`)
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error(`注册远程组件失败: ${pluginId}`, error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取远程组件信息
|
||||
* @param pluginId 插件ID
|
||||
* @returns 远程组件信息
|
||||
*/
|
||||
export function getRemoteComponent(pluginId: string): RemotePluginInfo | null {
|
||||
return registeredRemotes[pluginId] || null
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取和初始化远程组件
|
||||
* @param remoteUrl 远程组件URL
|
||||
@@ -127,3 +172,13 @@ export function clearRemoteComponentCache(remoteUrl?: string) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 取消注册远程组件
|
||||
export function unregisterRemoteComponent(pluginId: string) {
|
||||
if (registeredRemotes[pluginId]) {
|
||||
delete registeredRemotes[pluginId]
|
||||
console.log(`已取消注册远程组件: ${pluginId}`)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user