mirror of https://github.com/vuejs/core.git
fix: handling v-for on component with non-hydration node
This commit is contained in:
parent
4fc0247d0d
commit
db2f397e47
|
@ -1746,8 +1746,8 @@ describe('Vapor Mode hydration', () => {
|
||||||
<!--[-->
|
<!--[-->
|
||||||
<!--[--><span>a</span><!--]-->
|
<!--[--><span>a</span><!--]-->
|
||||||
<!--[--><span>b</span><!--]-->
|
<!--[--><span>b</span><!--]-->
|
||||||
<!--[--><span>c</span><!--for--><!--]-->
|
<!--[--><span>c</span><!--]-->
|
||||||
</div>"
|
<!--for--></div>"
|
||||||
`,
|
`,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1759,8 +1759,8 @@ describe('Vapor Mode hydration', () => {
|
||||||
<!--[-->
|
<!--[-->
|
||||||
<!--[--><span>a</span><!--]-->
|
<!--[--><span>a</span><!--]-->
|
||||||
<!--[--><span>b</span><!--]-->
|
<!--[--><span>b</span><!--]-->
|
||||||
<!--[--><span>c</span><span>d</span><!--slot--><!--for--><!--]-->
|
<!--[--><span>c</span><!--]-->
|
||||||
</div>"
|
<span>d</span><!--slot--><!--for--></div>"
|
||||||
`,
|
`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -1801,6 +1801,57 @@ describe('Vapor Mode hydration', () => {
|
||||||
`,
|
`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('on component with non-hydration node', async () => {
|
||||||
|
const data = ref({ show: true, msg: 'foo' })
|
||||||
|
const { container } = await testHydration(
|
||||||
|
`<template>
|
||||||
|
<div>
|
||||||
|
<components.Child v-for="item in 2" :key="item"/>
|
||||||
|
</div>
|
||||||
|
</template>`,
|
||||||
|
{
|
||||||
|
Child: `<template>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<div v-if="data.show">{{ data.msg }}</div>
|
||||||
|
</div>
|
||||||
|
<span>non-hydration node</span>
|
||||||
|
</div>
|
||||||
|
</template>`,
|
||||||
|
},
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
|
||||||
|
`
|
||||||
|
"<div>
|
||||||
|
<!--[--><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>"
|
||||||
|
`,
|
||||||
|
)
|
||||||
|
|
||||||
|
data.value.msg = 'bar'
|
||||||
|
await nextTick()
|
||||||
|
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
|
||||||
|
`
|
||||||
|
"<div>
|
||||||
|
<!--[--><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>"
|
||||||
|
`,
|
||||||
|
)
|
||||||
|
|
||||||
|
data.value.show = false
|
||||||
|
await nextTick()
|
||||||
|
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(`
|
||||||
|
"<div>
|
||||||
|
<!--[--><div><div><!--if--></div><span>non-hydration node</span></div><div><div><!--if--></div><span>non-hydration node</span></div><!--for--></div>"
|
||||||
|
`)
|
||||||
|
|
||||||
|
data.value.show = true
|
||||||
|
await nextTick()
|
||||||
|
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(`
|
||||||
|
"<div>
|
||||||
|
<!--[--><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>"
|
||||||
|
`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('slots', () => {
|
describe('slots', () => {
|
||||||
|
|
|
@ -30,8 +30,9 @@ import {
|
||||||
isHydrating,
|
isHydrating,
|
||||||
locateFragmentEndAnchor,
|
locateFragmentEndAnchor,
|
||||||
locateHydrationNode,
|
locateHydrationNode,
|
||||||
|
setCurrentHydrationNode,
|
||||||
} from './dom/hydration'
|
} from './dom/hydration'
|
||||||
import { ForFragment, VaporFragment } from './fragment'
|
import { ForFragment, VaporFragment, findLastChild } from './fragment'
|
||||||
import {
|
import {
|
||||||
insertionAnchor,
|
insertionAnchor,
|
||||||
insertionParent,
|
insertionParent,
|
||||||
|
@ -130,10 +131,20 @@ export const createFor = (
|
||||||
if (!isMounted) {
|
if (!isMounted) {
|
||||||
isMounted = true
|
isMounted = true
|
||||||
for (let i = 0; i < newLength; i++) {
|
for (let i = 0; i < newLength; i++) {
|
||||||
|
if (isHydrating && isComponent && i > 0) {
|
||||||
|
setCurrentHydrationNode(
|
||||||
|
findLastChild(newBlocks[i - 1].nodes)!.nextSibling,
|
||||||
|
)
|
||||||
|
}
|
||||||
mount(source, i)
|
mount(source, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHydrating) {
|
if (isHydrating) {
|
||||||
|
if (isComponent) {
|
||||||
|
setCurrentHydrationNode(
|
||||||
|
findLastChild(newBlocks[newLength - 1].nodes)!.nextSibling,
|
||||||
|
)
|
||||||
|
}
|
||||||
parentAnchor = locateFragmentEndAnchor()!
|
parentAnchor = locateFragmentEndAnchor()!
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
if (!parentAnchor) {
|
if (!parentAnchor) {
|
||||||
|
|
|
@ -157,7 +157,7 @@ export function normalizeAnchor(node: Block): Node | undefined {
|
||||||
if (node && node instanceof Node) {
|
if (node && node instanceof Node) {
|
||||||
return node
|
return node
|
||||||
} else if (isArray(node)) {
|
} else if (isArray(node)) {
|
||||||
return normalizeAnchor(node[0])
|
return normalizeAnchor(node[node.length - 1])
|
||||||
} else if (isVaporComponent(node)) {
|
} else if (isVaporComponent(node)) {
|
||||||
return normalizeAnchor(node.block!)
|
return normalizeAnchor(node.block!)
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue