await nextTick()
expect(html()).toBe('<div><div>B</div><!--dynamic-component--></div>')
})
+
+ test('fallback with dynamic slots', async () => {
+ const slotName = ref('default')
+ const { html } = define({
+ setup() {
+ return createDynamicComponent(() => 'div', null, {
+ $: [
+ () => ({
+ name: slotName.value,
+ fn: () => template('<span>hi</span>')(),
+ }),
+ ] as any,
+ })
+ },
+ }).render()
+
+ expect(html()).toBe(
+ '<div><span>hi</span><!--slot--></div><!--dynamic-component-->',
+ )
+
+ // update slot name
+ slotName.value = 'custom'
+ await nextTick()
+ expect(html()).toBe('<div><!--slot--></div><!--dynamic-component-->')
+
+ slotName.value = 'default'
+ await nextTick()
+ expect(html()).toBe(
+ '<div><span>hi</span><!--slot--></div><!--dynamic-component-->',
+ )
+ })
})
`,
)
})
+
+ test('dynamic component fallback with dynamic slots', async () => {
+ const data = ref({
+ name: 'default',
+ msg: 'foo',
+ })
+ const { container } = await testHydration(
+ `<template>
+ <component :is="'div'">
+ <template v-slot:[data.name]>
+ <span>{{ data.msg }}</span>
+ </template>
+ </component>
+ </template>`,
+ {},
+ data,
+ )
+
+ expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
+ `"<div><span>foo</span><!----></div><!--dynamic-component-->"`,
+ )
+
+ data.value.msg = 'bar'
+ await nextTick()
+ expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
+ `"<div><span>bar</span><!----></div><!--dynamic-component-->"`,
+ )
+ })
})
describe('if', () => {
setCurrentHydrationNode(el.firstChild)
}
if (rawSlots.$) {
- // TODO dynamic slot fragment
+ // ssr output does not contain the slot anchor, use an empty string
+ // as the anchor label to avoid slot anchor search errors
+ const frag = new DynamicFragment(
+ isHydrating ? '' : __DEV__ ? 'slot' : undefined,
+ )
+ renderEffect(() => frag.update(getSlot(rawSlots as RawSlots, 'default')))
+ if (!isHydrating) insert(frag, el)
} else {
- insert(getSlot(rawSlots as RawSlots, 'default')!(), el)
+ const block = getSlot(rawSlots as RawSlots, 'default')!()
+ if (!isHydrating) insert(block, el)
}
if (isHydrating) {
setCurrentHydrationNode(nextNode)