fix(components): [table] fix header HMR and keep v-if fallback (#22884)

* fix(components): [table] fix header HMR and keep v-if fallback

* fix(components): [table] return text VNode in header fallback
This commit is contained in:
余晖
2025-11-26 21:33:35 +08:00
committed by GitHub
parent 183360f316
commit 8170fca7ae
2 changed files with 34 additions and 4 deletions

View File

@@ -1,6 +1,8 @@
import {
Comment,
Fragment,
computed,
createTextVNode,
getCurrentInstance,
h,
ref,
@@ -16,7 +18,7 @@ import {
getDefaultClassName,
treeCellPrefix,
} from '../config'
import { parseMinWidth, parseWidth } from '../util'
import { ensureValidVNode, parseMinWidth, parseWidth } from '../util'
import type { ComputedRef, RendererNode, Slots, VNode } from 'vue'
import type { TableColumn, TableColumnCtx } from './defaults'
@@ -122,7 +124,17 @@ function useRender<T extends DefaultRow>(
column.renderHeader = (scope) => {
// help render
instance.columnConfig.value['label']
return renderSlot(slots, 'header', scope, () => [column.label])
if (slots.header) {
const slotResult = slots.header(scope)
// Manual valid check to support v-if fallback
// and bypass renderSlot to support HMR
if (ensureValidVNode(slotResult)) {
return h(Fragment, slotResult)
}
}
return createTextVNode(column.label)
}
}

View File

@@ -1,4 +1,4 @@
import { createVNode, isVNode, render } from 'vue'
import { Comment, Fragment, createVNode, isVNode, render } from 'vue'
import { flatMap, get, isNull, merge } from 'lodash-unified'
import {
ensureArray,
@@ -19,7 +19,7 @@ import ElTooltip, {
import type { DefaultRow, Table, TreeProps } from './table/defaults'
import type { TableColumnCtx } from './table-column/defaults'
import type { CSSProperties, VNode } from 'vue'
import type { CSSProperties, VNode, VNodeArrayChildren } from 'vue'
export type TableOverflowTooltipOptions = Partial<
Pick<
@@ -676,3 +676,21 @@ export const ensurePosition = (
style[key] = `${style[key]}px` as any
}
}
export function ensureValidVNode(
vnodes: VNodeArrayChildren
): VNodeArrayChildren | null {
return vnodes.some((child) => {
if (!isVNode(child)) return true
if (child.type === Comment) return false
if (
child.type === Fragment &&
!ensureValidVNode(child.children as VNodeArrayChildren)
) {
return false
}
return true
})
? vnodes
: null
}