mirror of https://github.com/vuejs/core.git
fix(runtime-core): ensure correct anchor el for unresolved async components (#13560)
close #13559
This commit is contained in:
parent
9b029239ed
commit
7f2994393d
|
@ -2230,5 +2230,57 @@ describe('Suspense', () => {
|
|||
fallback: [h('div'), h('div')],
|
||||
})
|
||||
})
|
||||
|
||||
// #13559
|
||||
test('renders multiple async components in Suspense with v-for and updates on items change', async () => {
|
||||
const CompAsyncSetup = defineAsyncComponent({
|
||||
props: ['item'],
|
||||
render(ctx: any) {
|
||||
return h('div', ctx.item.name)
|
||||
},
|
||||
})
|
||||
|
||||
const items = ref([
|
||||
{ id: 1, name: '111' },
|
||||
{ id: 2, name: '222' },
|
||||
{ id: 3, name: '333' },
|
||||
])
|
||||
|
||||
const Comp = {
|
||||
setup() {
|
||||
return () =>
|
||||
h(Suspense, null, {
|
||||
default: () =>
|
||||
h(
|
||||
Fragment,
|
||||
null,
|
||||
items.value.map(item =>
|
||||
h(CompAsyncSetup, { item, key: item.id }),
|
||||
),
|
||||
),
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
const root = nodeOps.createElement('div')
|
||||
render(h(Comp), root)
|
||||
await nextTick()
|
||||
await Promise.all(deps)
|
||||
|
||||
expect(serializeInner(root)).toBe(
|
||||
`<div>111</div><div>222</div><div>333</div>`,
|
||||
)
|
||||
|
||||
items.value = [
|
||||
{ id: 4, name: '444' },
|
||||
{ id: 5, name: '555' },
|
||||
{ id: 6, name: '666' },
|
||||
]
|
||||
await nextTick()
|
||||
await Promise.all(deps)
|
||||
expect(serializeInner(root)).toBe(
|
||||
`<div>444</div><div>555</div><div>666</div>`,
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1226,6 +1226,7 @@ function baseCreateRenderer(
|
|||
if (!initialVNode.el) {
|
||||
const placeholder = (instance.subTree = createVNode(Comment))
|
||||
processCommentNode(null, placeholder, container!, anchor)
|
||||
initialVNode.placeholder = placeholder.el
|
||||
}
|
||||
} else {
|
||||
setupRenderEffect(
|
||||
|
@ -1979,8 +1980,12 @@ function baseCreateRenderer(
|
|||
for (i = toBePatched - 1; i >= 0; i--) {
|
||||
const nextIndex = s2 + i
|
||||
const nextChild = c2[nextIndex] as VNode
|
||||
const anchorVNode = c2[nextIndex + 1] as VNode
|
||||
const anchor =
|
||||
nextIndex + 1 < l2 ? (c2[nextIndex + 1] as VNode).el : parentAnchor
|
||||
nextIndex + 1 < l2
|
||||
? // #13559, fallback to el placeholder for unresolved async component
|
||||
anchorVNode.el || anchorVNode.placeholder
|
||||
: parentAnchor
|
||||
if (newIndexToOldIndexMap[i] === 0) {
|
||||
// mount new
|
||||
patch(
|
||||
|
|
|
@ -196,6 +196,7 @@ export interface VNode<
|
|||
|
||||
// DOM
|
||||
el: HostNode | null
|
||||
placeholder: HostNode | null // async component el placeholder
|
||||
anchor: HostNode | null // fragment anchor
|
||||
target: HostElement | null // teleport target
|
||||
targetStart: HostNode | null // teleport target start anchor
|
||||
|
@ -711,6 +712,8 @@ export function cloneVNode<T, U>(
|
|||
suspense: vnode.suspense,
|
||||
ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
|
||||
ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
|
||||
placeholder: vnode.placeholder,
|
||||
|
||||
el: vnode.el,
|
||||
anchor: vnode.anchor,
|
||||
ctx: vnode.ctx,
|
||||
|
|
Loading…
Reference in New Issue