From 8170fca7aecf734488c80c6b6e2d820cd424ffbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=99=E6=99=96?= <1633875789@qq.com> Date: Wed, 26 Nov 2025 21:33:35 +0800 Subject: [PATCH] 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 --- .../table/src/table-column/render-helper.ts | 16 ++++++++++++-- packages/components/table/src/util.ts | 22 +++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/packages/components/table/src/table-column/render-helper.ts b/packages/components/table/src/table-column/render-helper.ts index 49992e95d7..1f78486d4f 100644 --- a/packages/components/table/src/table-column/render-helper.ts +++ b/packages/components/table/src/table-column/render-helper.ts @@ -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( 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) } } diff --git a/packages/components/table/src/util.ts b/packages/components/table/src/util.ts index f0bf291e6f..27a046330c 100644 --- a/packages/components/table/src/util.ts +++ b/packages/components/table/src/util.ts @@ -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 +}