添加 @originjs/vite-plugin-federation 依赖,并在多个组件中实现远程组件加载功能

This commit is contained in:
jxxghp
2025-05-05 21:26:53 +08:00
parent 48828fd72d
commit 047e827884
9 changed files with 230 additions and 96 deletions

View File

@@ -4,6 +4,7 @@ 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'
// 输入参数
const props = defineProps({
@@ -38,32 +39,12 @@ let pluginPageItems = ref([])
// Vue 模式:动态加载的组件
const dynamicComponent = computed(() => {
if (renderMode.value === 'vue' && vueComponentUrl.value) {
const url = vueComponentUrl.value
return defineAsyncComponent(() =>
api
.get(url)
.then((response: any) => {
if (response) {
const blob = new Blob([response.data], { type: 'text/javascript' })
const blobUrl = URL.createObjectURL(blob)
return import(/* @vite-ignore */ blobUrl)
} else {
return { render: () => h('div', '组件加载失败: 未读取到文件数据') }
}
})
.then(module => {
if (module.default) {
return module.default
} else {
console.error(`无法从 ${url} 加载默认导出的 Vue 组件`)
return { render: () => h('div', '组件加载失败: 无默认导出') }
}
})
.catch(err => {
console.error(`无法加载插件组件: ${url}`, err)
return { render: () => h('div', `组件加载失败:${err}`) }
}),
)
return loadRemoteComponent(vueComponentUrl.value, {
onError: error => {
console.error(`加载插件组件失败: ${vueComponentUrl.value}`, error)
$toast.error(`加载插件组件失败: ${error.message || '未知错误'}`)
},
})
}
return null
})
@@ -73,6 +54,11 @@ async function loadPluginUIData() {
isRefreshed.value = false
pluginPageItems.value = []
renderMode.value = 'vuetify'
// 如果存在旧的组件URL清除其缓存
if (vueComponentUrl.value) {
clearRemoteComponentCache(vueComponentUrl.value)
}
vueComponentUrl.value = null
try {
@@ -105,6 +91,13 @@ function handleAction() {
onMounted(() => {
loadPluginUIData()
})
// 组件卸载时清理资源
onUnmounted(() => {
if (vueComponentUrl.value) {
clearRemoteComponentCache(vueComponentUrl.value)
}
})
</script>
<template>
<VDialog scrollable max-width="80rem" :fullscreen="!display.mdAndUp.value">