From: Evan You Date: Tue, 11 Mar 2025 07:27:51 +0000 (+0800) Subject: wip(vapor): corresponding runtime behavior for if/for/slot-outlet post compiler change X-Git-Tag: v3.6.0-alpha.1~16^2~42 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6d7b901953ade1e6471612f39f5012b7afd1760;p=thirdparty%2Fvuejs%2Fcore.git wip(vapor): corresponding runtime behavior for if/for/slot-outlet post compiler change --- diff --git a/packages/runtime-vapor/src/apiCreateFor.ts b/packages/runtime-vapor/src/apiCreateFor.ts index 19653cd5da..0cd8317532 100644 --- a/packages/runtime-vapor/src/apiCreateFor.ts +++ b/packages/runtime-vapor/src/apiCreateFor.ts @@ -22,6 +22,8 @@ import { currentInstance, isVaporComponent } from './component' import type { DynamicSlot } from './componentSlots' import { renderEffect } from './renderEffect' import { VaporVForFlags } from '../../shared/src/vaporFlags' +import { isHydrating, locateHydrationNode } from './dom/hydration' +import { insertionAnchor, insertionParent } from './insertionState' class ForBlock extends VaporFragment { scope: EffectScope | undefined @@ -56,7 +58,6 @@ type ResolvedSource = { keys?: string[] } -/*! #__NO_SIDE_EFFECTS__ */ export const createFor = ( src: () => Source, renderItem: ( @@ -66,12 +67,18 @@ export const createFor = ( ) => Block, getKey?: (item: any, key: any, index?: number) => any, flags = 0, - // hydrationNode?: Node, ): VaporFragment => { + const _insertionParent = insertionParent + const _insertionAnchor = insertionAnchor + if (isHydrating) { + locateHydrationNode() + } + let isMounted = false let oldBlocks: ForBlock[] = [] let newBlocks: ForBlock[] let parent: ParentNode | undefined | null + // TODO handle this in hydration const parentAnchor = __DEV__ ? createComment('for') : createTextNode() const frag = new VaporFragment(oldBlocks) const instance = currentInstance! @@ -356,6 +363,11 @@ export const createFor = ( } else { renderEffect(renderList) } + + if (!isHydrating && _insertionParent) { + insert(frag, _insertionParent, _insertionAnchor) + } + return frag } diff --git a/packages/runtime-vapor/src/apiCreateIf.ts b/packages/runtime-vapor/src/apiCreateIf.ts index 947935f88b..71bfa32d5d 100644 --- a/packages/runtime-vapor/src/apiCreateIf.ts +++ b/packages/runtime-vapor/src/apiCreateIf.ts @@ -1,4 +1,6 @@ -import { type Block, type BlockFn, DynamicFragment } from './block' +import { type Block, type BlockFn, DynamicFragment, insert } from './block' +import { isHydrating, locateHydrationNode } from './dom/hydration' +import { insertionAnchor, insertionParent } from './insertionState' import { renderEffect } from './renderEffect' export function createIf( @@ -6,13 +8,24 @@ export function createIf( b1: BlockFn, b2?: BlockFn, once?: boolean, - // hydrationNode?: Node, ): Block { + const _insertionParent = insertionParent + const _insertionAnchor = insertionAnchor + if (isHydrating) { + locateHydrationNode() + } + + let frag: Block if (once) { - return condition() ? b1() : b2 ? b2() : [] + frag = condition() ? b1() : b2 ? b2() : [] } else { - const frag = __DEV__ ? new DynamicFragment('if') : new DynamicFragment() - renderEffect(() => frag.update(condition() ? b1 : b2)) - return frag + frag = __DEV__ ? new DynamicFragment('if') : new DynamicFragment() + renderEffect(() => (frag as DynamicFragment).update(condition() ? b1 : b2)) } + + if (!isHydrating && _insertionParent) { + insert(frag, _insertionParent, _insertionAnchor) + } + + return frag } diff --git a/packages/runtime-vapor/src/componentSlots.ts b/packages/runtime-vapor/src/componentSlots.ts index 9f6c2ba5a0..0d3dcb9e28 100644 --- a/packages/runtime-vapor/src/componentSlots.ts +++ b/packages/runtime-vapor/src/componentSlots.ts @@ -1,9 +1,11 @@ import { EMPTY_OBJ, NO, hasOwn, isArray, isFunction } from '@vue/shared' -import { type Block, type BlockFn, DynamicFragment } from './block' +import { type Block, type BlockFn, DynamicFragment, insert } from './block' import { rawPropsProxyHandlers } from './componentProps' import { currentInstance, isRef } from '@vue/runtime-dom' import type { LooseRawProps, VaporComponentInstance } from './component' import { renderEffect } from './renderEffect' +import { insertionAnchor, insertionParent } from './insertionState' +import { isHydrating, locateHydrationNode } from './dom/hydration' export type RawSlots = Record & { $?: DynamicSlotSource[] @@ -90,6 +92,12 @@ export function createSlot( rawProps?: LooseRawProps | null, fallback?: VaporSlot, ): Block { + const _insertionParent = insertionParent + const _insertionAnchor = insertionAnchor + if (isHydrating) { + locateHydrationNode() + } + const instance = currentInstance as VaporComponentInstance const rawSlots = instance.rawSlots const slotProps = rawProps @@ -135,5 +143,9 @@ export function createSlot( renderSlot() } + if (!isHydrating && _insertionParent) { + insert(fragment, _insertionParent, _insertionAnchor) + } + return fragment }