Skip to content

Commit 2ef3caa

Browse files
committed
fix: handling v-for on component with non-hydration node
1 parent 576e93a commit 2ef3caa

File tree

2 files changed

+67
-4
lines changed

2 files changed

+67
-4
lines changed

packages/runtime-vapor/__tests__/hydration.spec.ts

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,8 +1766,8 @@ describe('Vapor Mode hydration', () => {
17661766
<!--[-->
17671767
<!--[--><span>a</span><!--]-->
17681768
<!--[--><span>b</span><!--]-->
1769-
<!--[--><span>c</span><!--for--><!--]-->
1770-
</div>"
1769+
<!--[--><span>c</span><!--]-->
1770+
<!--for--></div>"
17711771
`,
17721772
)
17731773

@@ -1779,8 +1779,8 @@ describe('Vapor Mode hydration', () => {
17791779
<!--[-->
17801780
<!--[--><span>a</span><!--]-->
17811781
<!--[--><span>b</span><!--]-->
1782-
<!--[--><span>c</span><span>d</span><!--slot--><!--for--><!--]-->
1783-
</div>"
1782+
<!--[--><span>c</span><!--]-->
1783+
<span>d</span><!--slot--><!--for--></div>"
17841784
`,
17851785
)
17861786
})
@@ -1821,6 +1821,57 @@ describe('Vapor Mode hydration', () => {
18211821
`,
18221822
)
18231823
})
1824+
1825+
test('on component with non-hydration node', async () => {
1826+
const data = ref({ show: true, msg: 'foo' })
1827+
const { container } = await testHydration(
1828+
`<template>
1829+
<div>
1830+
<components.Child v-for="item in 2" :key="item"/>
1831+
</div>
1832+
</template>`,
1833+
{
1834+
Child: `<template>
1835+
<div>
1836+
<div>
1837+
<div v-if="data.show">{{ data.msg }}</div>
1838+
</div>
1839+
<span>non-hydration node</span>
1840+
</div>
1841+
</template>`,
1842+
},
1843+
data,
1844+
)
1845+
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
1846+
`
1847+
"<div>
1848+
<!--[--><div><div><div>foo</div><!--if--></div><span>non-hydration node</span></div><div><div><div>foo</div><!--if--></div><span>non-hydration node</span></div><!--for--></div>"
1849+
`,
1850+
)
1851+
1852+
data.value.msg = 'bar'
1853+
await nextTick()
1854+
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
1855+
`
1856+
"<div>
1857+
<!--[--><div><div><div>bar</div><!--if--></div><span>non-hydration node</span></div><div><div><div>bar</div><!--if--></div><span>non-hydration node</span></div><!--for--></div>"
1858+
`,
1859+
)
1860+
1861+
data.value.show = false
1862+
await nextTick()
1863+
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(`
1864+
"<div>
1865+
<!--[--><div><div><!--if--></div><span>non-hydration node</span></div><div><div><!--if--></div><span>non-hydration node</span></div><!--for--></div>"
1866+
`)
1867+
1868+
data.value.show = true
1869+
await nextTick()
1870+
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(`
1871+
"<div>
1872+
<!--[--><div><div><div>bar</div><!--if--></div><span>non-hydration node</span></div><div><div><div>bar</div><!--if--></div><span>non-hydration node</span></div><!--for--></div>"
1873+
`)
1874+
})
18241875
})
18251876

18261877
describe('slots', () => {

packages/runtime-vapor/src/apiCreateFor.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { createComment, createTextNode } from './dom/node'
1616
import {
1717
type Block,
1818
VaporFragment,
19+
findLastChild,
1920
insert,
2021
remove as removeBlock,
2122
} from './block'
@@ -29,6 +30,7 @@ import {
2930
isHydrating,
3031
locateFragmentEndAnchor,
3132
locateHydrationNode,
33+
setCurrentHydrationNode,
3234
} from './dom/hydration'
3335
import {
3436
insertionAnchor,
@@ -126,10 +128,20 @@ export const createFor = (
126128
if (!isMounted) {
127129
isMounted = true
128130
for (let i = 0; i < newLength; i++) {
131+
if (isHydrating && isComponent && i > 0) {
132+
setCurrentHydrationNode(
133+
findLastChild(newBlocks[i - 1].nodes)!.nextSibling,
134+
)
135+
}
129136
mount(source, i)
130137
}
131138

132139
if (isHydrating) {
140+
if (isComponent) {
141+
setCurrentHydrationNode(
142+
findLastChild(newBlocks[newLength - 1].nodes)!.nextSibling,
143+
)
144+
}
133145
parentAnchor = locateFragmentEndAnchor()!
134146
if (__DEV__) {
135147
if (!parentAnchor) {

0 commit comments

Comments
 (0)