修改内容区显示逻辑,改为配置驱动
This commit is contained in:
@@ -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 }
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user