Files
JoyD/AutoRobot/Windows/Robot/Web/src/DockLayout/Render.vue
2025-12-31 12:17:54 +08:00

121 lines
3.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- 根据type属性动态渲染对应的组件 -->
<component
:is="componentType"
v-bind="componentProps"
>
<!-- 统一处理children属性不区分组件类型只要有children就渲染 -->
<template v-if="config.children">
<!-- 统一处理children为数组或单个对象的情况 -->
<div v-for="child in Array.isArray(config.children) ? config.children : [config.children]" :key="child.id" style="width: 100%; height: 100%;">
<Render
:type="child.type"
:config="child"
:debug="debug"
/>
</div>
</template>
</component>
</template>
<script setup>
import { computed, defineAsyncComponent } from 'vue'
const Area = defineAsyncComponent(() => import('./Area.vue'))
const TabPage = defineAsyncComponent(() => import('./TabPage.vue'))
const Panel = defineAsyncComponent(() => import('./Panel.vue'))
import { eventBus, EVENT_TYPES } from './eventBus'
// 定义组件属性
const props = defineProps({
// 组件类型area, TabPage, panel
type: {
type: String,
required: true,
validator: (value) => ['Area', 'TabPage', 'Panel'].includes(value)
},
// 组件配置数据
config: {
type: Object,
required: true
},
// 是否转发所有事件(用于调试)
debug: {
type: Boolean,
default: false
}
})
// 不再需要定义emit因为事件将通过事件总线发送
// 根据type计算要渲染的组件
const componentType = computed(() => {
const typeMap = {
'Area': Area,
'TabPage': TabPage,
'Panel': Panel
}
return typeMap[props.type]
})
// 根据type和config计算组件的属性
const componentProps = computed(() => {
const { config } = props
switch (props.type) {
case 'Area':
return {
id: config.id,
title: config.title || '面板区',
resizable: config.resizable !== false,
windowState: config.windowState || '正常',
width: config.width || 300,
height: config.height || 250,
showTitleBar: config.showTitleBar !== false,
left: config.left,
top: config.top,
draggable: config.draggable !== false,
children: config.children
}
case 'TabPage':
return {
id: config.id,
title: config.title || '标签页',
showTabs: config.showTabs !== false,
tabPosition: config.tabPosition || 'top',
children: config.children
}
case 'Panel':
return {
id: config.id,
title: config.title || '',
x: config.x || 0,
y: config.y || 0,
width: config.width || 300,
height: config.height || 200,
collapsed: config.collapsed || false,
toolbarExpanded: config.toolbarExpanded || false,
maximized: config.maximized || false,
content: config.content
}
default:
return {}
}
})
// 暴露组件实例方法
defineExpose({
getComponentType: () => props.type,
getConfig: () => props.config,
getComponentProps: () => componentProps.value,
isDebugMode: () => props.debug
})
</script>
<style scoped>
/* Render组件本身不添加额外样式由子组件控制 */
</style>