wip(vapor): corresponding runtime behavior for if/for/slot-outlet post compiler change

This commit is contained in:
Evan You 2025-03-11 15:27:51 +08:00
parent 9722574744
commit f6d7b90195
No known key found for this signature in database
GPG Key ID: 00E9AB7A6704CE0A
3 changed files with 48 additions and 11 deletions

View File

@ -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
}

View File

@ -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 {
if (once) {
return condition() ? b1() : b2 ? b2() : []
} else {
const frag = __DEV__ ? new DynamicFragment('if') : new DynamicFragment()
renderEffect(() => frag.update(condition() ? b1 : b2))
return frag
const _insertionParent = insertionParent
const _insertionAnchor = insertionAnchor
if (isHydrating) {
locateHydrationNode()
}
let frag: Block
if (once) {
frag = condition() ? b1() : b2 ? b2() : []
} else {
frag = __DEV__ ? new DynamicFragment('if') : new DynamicFragment()
renderEffect(() => (frag as DynamicFragment).update(condition() ? b1 : b2))
}
if (!isHydrating && _insertionParent) {
insert(frag, _insertionParent, _insertionAnchor)
}
return frag
}

View File

@ -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<string, VaporSlot> & {
$?: 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
}