修改内容区显示逻辑,改为配置驱动

This commit is contained in:
zqm
2025-12-26 17:12:36 +08:00
parent e89d3254e8
commit 09e4076635
5 changed files with 213 additions and 210 deletions

View File

@@ -87,10 +87,16 @@
<!-- Tab页内容区域 -->
<div class="tab-content">
<!-- 直接渲染插槽内容 -->
<slot></slot>
<!-- 使用Render组件渲染children配置 -->
<div v-for="child in Array.isArray(children) ? children : [children]" :key="child.id" style="width: 100%; height: 100%;">
<Render
:type="child.type"
:config="child"
/>
</div>
<!-- 空状态提示 -->
<div v-if="slotItems.length === 0" class="tab-empty">
<div v-if="!children || (Array.isArray(children) && children.length === 0)" class="tab-empty">
<span>没有可显示的内容</span>
</div>
</div>
@@ -126,10 +132,9 @@
</template>
<script setup>
import { defineProps, ref, onMounted, onUnmounted, computed, useSlots } from 'vue'
import { defineProps, ref, onMounted, onUnmounted, computed } from 'vue'
import { emitEvent, EVENT_TYPES } from './eventBus'
const slots = useSlots()
import Render from './Render.vue'
const props = defineProps({
id: { type: String, required: true },
@@ -157,33 +162,39 @@ let isDragging = false
let dragIndex = -1
let currentDragId = null
// 计算属性:获取插槽项的props
// 计算属性:获取子组件项的props
const slotItems = computed(() => {
if (!slots.default) return []
const slotChildren = slots.default()
return slotChildren.map(child => child?.props || {})
if (!props.children) return []
const childrenArray = Array.isArray(props.children) ? props.children : [props.children]
return childrenArray.map(child => child || {})
})
// 计算属性:控制标签栏的显示
const shouldShowTabs = computed(() => {
// 显示标签栏的条件showTabs为true且有子组件
return props.showTabs && slots.default && slots.default().length > 0
// 显示标签栏的条件showTabs为true且有多个子组件
if (!props.children) return false
const childrenCount = Array.isArray(props.children) ? props.children.length : 1
return props.showTabs && childrenCount > 1
})
// 设置激活的标签页
const setActiveTab = (index) => {
const slotChildren = slots.default ? slots.default() : []
if (index >= 0 && index < slotChildren.length) {
if (!props.children) return
const childrenArray = Array.isArray(props.children) ? props.children : [props.children]
if (index >= 0 && index < childrenArray.length) {
activeTabIndex.value = index
emitEvent(EVENT_TYPES.TAB_CHANGE, { index, tab: slotChildren[index] })
emitEvent(EVENT_TYPES.TAB_CHANGE, { index, tab: childrenArray[index] })
}
}
// 组件挂载后,如果有子组件且没有激活的标签,默认激活第一个
onMounted(() => {
const slotChildren = slots.default ? slots.default() : []
if (slotChildren.length > 0 && activeTabIndex.value === -1) {
setActiveTab(0)
if (props.children) {
const childrenCount = Array.isArray(props.children) ? props.children.length : 1
if (childrenCount > 0 && activeTabIndex.value === -1) {
setActiveTab(0)
}
}
})
@@ -202,13 +213,20 @@ const onTabDragStart = (index, event) => {
// 生成统一的 dragId
currentDragId = `tabpage_${props.id}_${index}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`
// 获取tabId
let tabId = null
if (props.children) {
const childrenArray = Array.isArray(props.children) ? props.children : [props.children]
tabId = childrenArray[index]?.id || `tab-${index}`
}
// 传递标签页索引和鼠标位置,包含 dragId
emitEvent(EVENT_TYPES.TAB_DRAG_START, {
dragId: currentDragId,
clientX: event.clientX,
clientY: event.clientY,
tabIndex: index,
tabId: $slots.default()[index]?.props?.id
tabId: tabId
}, {
source: { component: 'TabPage', tabPageId: props.id, tabIndex: index, dragId: currentDragId }
})