From: daiwei Date: Fri, 30 May 2025 08:27:02 +0000 (+0800) Subject: fix(vdomInterop): handle forwarded vapor slots during render VDOM slot X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=389678063b54b45485c5f47daade4029af6db4cd;p=thirdparty%2Fvuejs%2Fcore.git fix(vdomInterop): handle forwarded vapor slots during render VDOM slot --- diff --git a/packages/runtime-vapor/src/componentProps.ts b/packages/runtime-vapor/src/componentProps.ts index 6de001ffb9..9cf65c5714 100644 --- a/packages/runtime-vapor/src/componentProps.ts +++ b/packages/runtime-vapor/src/componentProps.ts @@ -214,7 +214,8 @@ export function hasAttrFromRawProps(rawProps: RawProps, key: string): boolean { if (dynamicSources) { let i = dynamicSources.length while (i--) { - if (hasOwn(resolveSource(dynamicSources[i]), key)) { + const source = resolveSource(dynamicSources[i]) + if (source && hasOwn(source, key)) { return true } } diff --git a/packages/runtime-vapor/src/vdomInterop.ts b/packages/runtime-vapor/src/vdomInterop.ts index 6db627f03b..33f6d4ca80 100644 --- a/packages/runtime-vapor/src/vdomInterop.ts +++ b/packages/runtime-vapor/src/vdomInterop.ts @@ -29,7 +29,14 @@ import { mountComponent, unmountComponent, } from './component' -import { type Block, VaporFragment, insert, remove } from './block' +import { + type Block, + VaporFragment, + insert, + isFragment, + isValidBlock, + remove, +} from './block' import { EMPTY_OBJ, extend, isFunction } from '@vue/shared' import { type RawProps, rawPropsProxyHandlers } from './componentProps' import type { RawSlots, VaporSlot } from './componentSlots' @@ -279,7 +286,36 @@ function renderVDOMSlot( false, ) } else { - if ((vnode.children as any[]).length) { + let isValidSlotContent + let children = vnode.children as any[] + /* + * Handle forwarded vapor slot inside VDOM slot + * Example: In a vapor component template: + * + * + * + */ + let vaporSlot + if (children.length === 1 && (vaporSlot = children[0].vs)) { + const block = vaporSlot.slot(props) + isValidSlotContent = + isValidBlock(block) || + /* + * If block is a vapor fragment with insert, it indicates a forwarded VDOM slot + * Example: In a VDOM component template: + * + * + * + */ + (isFragment(block) && block.insert) + } else { + isValidSlotContent = children.length > 0 + } + if (isValidSlotContent) { if (fallbackNodes) { remove(fallbackNodes, parentNode) fallbackNodes = undefined