diff --git a/packages/runtime-vapor/__tests__/apiCreateDynamicComponent.spec.ts b/packages/runtime-vapor/__tests__/apiCreateDynamicComponent.spec.ts index 2f6cd7b3f39..5ab9ed3ca68 100644 --- a/packages/runtime-vapor/__tests__/apiCreateDynamicComponent.spec.ts +++ b/packages/runtime-vapor/__tests__/apiCreateDynamicComponent.spec.ts @@ -1,6 +1,11 @@ import { shallowRef } from '@vue/reactivity' import { nextTick } from '@vue/runtime-dom' -import { createDynamicComponent } from '../src' +import { + createDynamicComponent, + defineVaporComponent, + setInsertionState, + template, +} from '../src' import { makeRender } from './_utils' const define = makeRender() @@ -54,4 +59,34 @@ describe('api: createDynamicComponent', () => { await nextTick() expect(html()).toBe('') }) + + test('switch dynamic component children', async () => { + const CompA = defineVaporComponent({ + setup() { + return template('
A
')() + }, + }) + const CompB = defineVaporComponent({ + setup() { + return template('
B
')() + }, + }) + + const current = shallowRef(CompA) + const { html } = define({ + setup() { + const t1 = template('
') + const n2 = t1() as any + setInsertionState(n2) + createDynamicComponent(() => current.value) + return n2 + }, + }).render() + + expect(html()).toBe('
A
') + + current.value = CompB + await nextTick() + expect(html()).toBe('
B
') + }) }) diff --git a/packages/runtime-vapor/src/block.ts b/packages/runtime-vapor/src/block.ts index b782afd38d3..9b06f3c6950 100644 --- a/packages/runtime-vapor/src/block.ts +++ b/packages/runtime-vapor/src/block.ts @@ -8,6 +8,7 @@ import { import { createComment, createTextNode } from './dom/node' import { EffectScope, pauseTracking, resetTracking } from '@vue/reactivity' import { isHydrating } from './dom/hydration' +import { insertionAnchor, insertionParent } from './insertionState' export type Block = | Node @@ -47,6 +48,9 @@ export class DynamicFragment extends VaporFragment { } this.current = key + const _insertionParent = insertionParent + const _insertionAnchor = insertionAnchor + pauseTracking() const parent = this.anchor.parentNode @@ -59,7 +63,11 @@ export class DynamicFragment extends VaporFragment { if (render) { this.scope = new EffectScope() this.nodes = this.scope.run(render) || [] - if (parent) insert(this.nodes, parent, this.anchor) + if (parent) { + insert(this.nodes, parent, this.anchor) + } else if (!isHydrating && _insertionParent) { + insert(this.anchor, _insertionParent, _insertionAnchor) + } } else { this.scope = undefined this.nodes = []