mirror of https://github.com/vuejs/core.git
feat(hydration): handle consecutive prepend
This commit is contained in:
parent
80e6ea8730
commit
6606cbdb4b
|
@ -2511,6 +2511,56 @@ describe('Vapor Mode hydration', () => {
|
|||
)
|
||||
})
|
||||
|
||||
test('consecutive slots prepend', async () => {
|
||||
const data = reactive({
|
||||
msg1: 'foo',
|
||||
msg2: 'bar',
|
||||
msg3: 'baz',
|
||||
})
|
||||
|
||||
const { container } = await testHydration(
|
||||
`<template>
|
||||
<components.Child>
|
||||
<template #foo>
|
||||
<span>{{data.msg1}}</span>
|
||||
</template>
|
||||
<template #bar>
|
||||
<span>{{data.msg2}}</span>
|
||||
</template>
|
||||
</components.Child>
|
||||
</template>`,
|
||||
{
|
||||
Child: `<template>
|
||||
<div>
|
||||
<slot name="foo"/>
|
||||
<slot name="bar"/>
|
||||
<div>{{data.msg3}}</div>
|
||||
</div>
|
||||
</template>`,
|
||||
},
|
||||
data,
|
||||
)
|
||||
|
||||
expect(container.innerHTML).toBe(
|
||||
`<div>` +
|
||||
`<!--[--><span>foo</span><!--]--><!--${slotAnchorLabel}-->` +
|
||||
`<!--[--><span>bar</span><!--]--><!--${slotAnchorLabel}-->` +
|
||||
`<div>baz</div>` +
|
||||
`</div>`,
|
||||
)
|
||||
|
||||
data.msg1 = 'hello'
|
||||
data.msg2 = 'vapor'
|
||||
await nextTick()
|
||||
expect(container.innerHTML).toBe(
|
||||
`<div>` +
|
||||
`<!--[--><span>hello</span><!--]--><!--${slotAnchorLabel}-->` +
|
||||
`<!--[--><span>vapor</span><!--]--><!--${slotAnchorLabel}-->` +
|
||||
`<div>baz</div>` +
|
||||
`</div>`,
|
||||
)
|
||||
})
|
||||
|
||||
test('slot fallback', async () => {
|
||||
const data = reactive({
|
||||
foo: 'foo',
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
} from '../insertionState'
|
||||
import {
|
||||
__next,
|
||||
__nthChild,
|
||||
_nthChild,
|
||||
disableHydrationNodeLookup,
|
||||
enableHydrationNodeLookup,
|
||||
|
@ -39,6 +40,7 @@ function performHydration<T>(
|
|||
// optimize anchor cache lookup
|
||||
;(Comment.prototype as any).$fe = undefined
|
||||
;(Node.prototype as any).$dp = undefined
|
||||
;(Node.prototype as any).$np = undefined
|
||||
isOptimized = true
|
||||
}
|
||||
enableHydrationNodeLookup()
|
||||
|
@ -122,7 +124,9 @@ function locateHydrationNodeImpl(isFragment?: boolean): void {
|
|||
let node: Node | null
|
||||
// prepend / firstChild
|
||||
if (insertionAnchor === 0) {
|
||||
node = insertionParent!.firstChild
|
||||
const n = insertionParent!.$np || 0
|
||||
node = __nthChild(insertionParent!, n)
|
||||
insertionParent!.$np = n + 1
|
||||
} else if (insertionAnchor) {
|
||||
// `insertionAnchor` is a Node, it is the DOM node to hydrate
|
||||
// Template: `...<span/><!----><span/>...`// `insertionAnchor` is the placeholder
|
||||
|
|
|
@ -12,6 +12,10 @@ export let insertionParent:
|
|||
// const n4 = t0(2) // n4.$dp = 2
|
||||
// The first 2 nodes are static, dynamic nodes start from index 2
|
||||
$dp?: number
|
||||
// number of prepends - hydration only
|
||||
// consecutive prepends need to skip nodes that were prepended earlier
|
||||
// each prepend increases the value of $prepend
|
||||
$np?: number
|
||||
})
|
||||
| undefined
|
||||
export let insertionAnchor: Node | 0 | undefined
|
||||
|
|
Loading…
Reference in New Issue