fix: Component awlays reset
This commit is contained in:
@@ -44,11 +44,13 @@
|
||||
</CollapsibleSection>
|
||||
|
||||
<CollapsibleSection title="组件功能" v-model:isExpanded="componentCapsExpanded" status="default" class="mt-4">
|
||||
<div v-if="componentData && componentData.type">
|
||||
<component v-if="capabilityComponent" :is="capabilityComponent" v-bind="componentData.attrs" />
|
||||
<div v-else class="text-gray-400">该组件没有提供特殊功能</div>
|
||||
<div id="ComponentCapabilities" ref="ComponentCapabilities"></div>
|
||||
<div v-if="!(componentData && componentData.type)" class="text-gray-400">
|
||||
选择元件以查看其功能
|
||||
</div>
|
||||
<div v-else-if="!componentCaps?.hasChildNodes()" class="text-gray-400">
|
||||
该组件没有提供特殊功能
|
||||
</div>
|
||||
<div v-else class="text-gray-400">选择元件以查看其功能</div>
|
||||
</CollapsibleSection>
|
||||
|
||||
<!-- 未来可以在这里添加更多的分区 -->
|
||||
@@ -71,9 +73,12 @@ import { type PropertyConfig } from "@/components/equipments/componentConfig"; /
|
||||
import CollapsibleSection from "./CollapsibleSection.vue"; // 可折叠区域组件
|
||||
import PropertyEditor from "./PropertyEditor.vue"; // 属性编辑器组件
|
||||
import DDSPropertyEditor from "./equipments/DDSPropertyEditor.vue"; // DDS专用属性编辑器组件
|
||||
import { ref, computed, watch, shallowRef, markRaw, h, createApp } from "vue"; // Vue核心API
|
||||
import { isNull, isUndefined } from "lodash";
|
||||
import type { JSX } from "vue/jsx-runtime";
|
||||
import {
|
||||
ref,
|
||||
computed,
|
||||
watch,
|
||||
useTemplateRef,
|
||||
} from "vue"; // Vue核心API
|
||||
|
||||
// 引脚接口定义
|
||||
interface Pin {
|
||||
@@ -95,6 +100,8 @@ const pinsSectionExpanded = ref(false); // 引脚配置区域默认折叠
|
||||
const componentCapsExpanded = ref(true); // 组件功能区域默认展开
|
||||
const wireSectionExpanded = ref(false); // 连线管理区域默认折叠
|
||||
|
||||
const componentCaps = useTemplateRef("ComponentCapabilities");
|
||||
|
||||
// DDS组件特殊属性的本地状态
|
||||
const ddsProperties = ref({
|
||||
frequency: 1000, // 频率,默认1000Hz
|
||||
@@ -207,129 +214,6 @@ function updateDDSProperties(newProperties: any) {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 存储当前选中组件的能力组件
|
||||
const capabilityComponent = shallowRef<JSX.Element>();
|
||||
|
||||
// 获取组件实例上暴露的方法
|
||||
async function getExposedCapabilities(componentType: string) {
|
||||
try {
|
||||
// 动态导入组件
|
||||
const module = await import(`./equipments/${componentType}.vue`);
|
||||
const Component = module.default;
|
||||
|
||||
// 创建一个临时div作为挂载点
|
||||
const tempDiv = document.createElement("div");
|
||||
|
||||
// 创建临时应用实例并挂载组件
|
||||
let exposedMethods: any = null;
|
||||
const app = createApp({
|
||||
render() {
|
||||
return h(Component, {
|
||||
ref: (el: any) => {
|
||||
if (el) {
|
||||
// 获取组件实例暴露的方法
|
||||
exposedMethods = el;
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// 挂载应用
|
||||
const vm = app.mount(tempDiv);
|
||||
|
||||
// 确保实例已创建并获取到暴露的方法
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
// 检查是否有getCapabilities方法
|
||||
if (
|
||||
exposedMethods &&
|
||||
typeof exposedMethods.getCapabilities === "function"
|
||||
) {
|
||||
// 获取能力组件定义
|
||||
const CapabilityComponent = exposedMethods.getCapabilities();
|
||||
|
||||
// 卸载应用,清理DOM
|
||||
app.unmount();
|
||||
tempDiv.remove();
|
||||
|
||||
return CapabilityComponent;
|
||||
}
|
||||
|
||||
// 卸载应用,清理DOM
|
||||
app.unmount();
|
||||
tempDiv.remove();
|
||||
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.error(`获取${componentType}能力页面失败:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 监听选中组件变化,动态加载能力组件
|
||||
watch(
|
||||
() => props.componentData,
|
||||
async (newComponentData) => {
|
||||
if (newComponentData && newComponentData.type) {
|
||||
try {
|
||||
// 首先尝试从实例中获取暴露的方法
|
||||
let capsComponent = null;
|
||||
if (!isUndefined( newComponentData.capsPage ) && !isNull(newComponentData.capsPage)) {
|
||||
capsComponent = newComponentData.capsPage;
|
||||
capabilityComponent.value = markRaw(capsComponent);
|
||||
}
|
||||
else
|
||||
capsComponent = await getExposedCapabilities(newComponentData.type);
|
||||
|
||||
if (capsComponent) {
|
||||
capabilityComponent.value = markRaw(capsComponent);
|
||||
newComponentData.capsPage = capsComponent;
|
||||
console.log(`已从实例加载${newComponentData.type}组件的能力页面`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果实例方法获取失败,回退到模块导出方法
|
||||
const module = await import(
|
||||
`./equipments/${newComponentData.type}.vue`
|
||||
);
|
||||
|
||||
if (
|
||||
(module.default &&
|
||||
typeof module.default.getCapabilities === "function") ||
|
||||
typeof module.getCapabilities === "function"
|
||||
) {
|
||||
const getCapsFn =
|
||||
typeof module.getCapabilities === "function"
|
||||
? module.getCapabilities
|
||||
: module.default.getCapabilities;
|
||||
|
||||
const moduleCapComponent = getCapsFn();
|
||||
if (moduleCapComponent) {
|
||||
capabilityComponent.value = markRaw(moduleCapComponent);
|
||||
console.log(`已从模块加载${newComponentData.type}组件的能力页面`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
capabilityComponent.value = null;
|
||||
console.log(`组件${newComponentData.type}没有提供getCapabilities方法`);
|
||||
} catch (error) {
|
||||
console.error(`加载组件${newComponentData.type}能力页面失败:`, error);
|
||||
capabilityComponent.value = null;
|
||||
}
|
||||
} else {
|
||||
capabilityComponent.value = null;
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
// 修改hasComponentCaps计算属性
|
||||
const hasComponentCaps = computed(() => {
|
||||
return capabilityComponent.value !== null;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user