wip(vapor): fix children gen for dynamic with anchor insertion

This commit is contained in:
Evan You 2025-03-11 20:32:07 +08:00
parent a51dd42dc6
commit 2a76b52d7f
No known key found for this signature in database
GPG Key ID: 00E9AB7A6704CE0A
4 changed files with 62 additions and 2 deletions

View File

@ -1,5 +1,22 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`compiler: children transform > anchor insertion in middle 1`] = `
"import { child as _child, next as _next, setInsertionState as _setInsertionState, createIf as _createIf, template as _template } from 'vue';
const t0 = _template("<div></div>")
const t1 = _template("<div><div></div><!><div></div></div>", true)
export function render(_ctx) {
const n4 = t1()
const n3 = _next(_child(n4))
_setInsertionState(n4, n3)
const n0 = _createIf(() => (1), () => {
const n2 = t0()
return n2
}, null, true)
return n4
}"
`;
exports[`compiler: children transform > children & sibling references 1`] = `
"import { child as _child, next as _next, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("<div><p> </p> <p> </p></div>", true)

View File

@ -59,4 +59,18 @@ describe('compiler: children transform', () => {
expect(code).contains(`const n0 = _nthChild(n1, 2)`)
expect(code).toMatchSnapshot()
})
test('anchor insertion in middle', () => {
const { code } = compileWithElementTransform(
`<div>
<div></div>
<div v-if="1"></div>
<div></div>
</div>`,
)
// ensure the insertion anchor is generated before the insertion statement
expect(code).toMatch(`const n3 = _next(_child(n4))
_setInsertionState(n4, n3)`)
expect(code).toMatchSnapshot()
})
})

View File

@ -94,16 +94,24 @@ export function genChildren(
push(...init)
}
}
if (id === child.anchor) {
push(...genSelf(child, context))
}
if (id !== undefined) {
push(...genDirectivesForElement(id, context))
}
prev = [variable, elementIndex]
childrenToGen.push([child, variable])
}
if (childrenToGen.length) {
for (const [child, from] of childrenToGen) {
push(...genChildren(child, context, from))
}
}
return frag
}

View File

@ -239,6 +239,27 @@ describe('Vapor Mode hydration', () => {
)
})
// problem is the <!> placeholder does not exist in SSR output
test.todo('component with anchor insertion', async () => {
const { container, data } = await testHydration(
`
<template><div><span/><components.Child/><span/></div></template>
`,
{
Child: `<template>{{ data }}</template>`,
},
)
expect(container.innerHTML).toMatchInlineSnapshot(
`"<div><span></span>foo<span></span></div>"`,
)
data.value = 'bar'
await nextTick()
expect(container.innerHTML).toMatchInlineSnapshot(
`"<div><span></span>foo<span></span></div>"`,
)
})
test.todo('if')
test.todo('for')