fix(suspense): fix suspense nested child updates in template mode
fix #2214
This commit is contained in:
parent
128ec460ec
commit
0227b4a697
@ -14,6 +14,7 @@ import {
|
||||
onErrorCaptured,
|
||||
shallowRef
|
||||
} from '@vue/runtime-test'
|
||||
import { createApp } from 'vue'
|
||||
|
||||
describe('Suspense', () => {
|
||||
const deps: Promise<any>[] = []
|
||||
@ -1068,4 +1069,28 @@ describe('Suspense', () => {
|
||||
expect(serializeInner(root)).toBe(`<div>two</div>`)
|
||||
expect(calls).toEqual([`one mounted`, `one unmounted`, `two mounted`])
|
||||
})
|
||||
|
||||
// #2214
|
||||
// Since suspense renders its own root like a component, it should not patch
|
||||
// its content in optimized mode.
|
||||
test('should not miss nested element updates when used in templates', async () => {
|
||||
const n = ref(1)
|
||||
const Comp = {
|
||||
setup() {
|
||||
return { n }
|
||||
},
|
||||
template: `
|
||||
<Suspense>
|
||||
<div><span>{{ n }}</span></div>
|
||||
</Suspense>
|
||||
`
|
||||
}
|
||||
const root = document.createElement('div')
|
||||
createApp(Comp).mount(root)
|
||||
expect(root.innerHTML).toBe(`<div><span>1</span></div>`)
|
||||
|
||||
n.value++
|
||||
await nextTick()
|
||||
expect(root.innerHTML).toBe(`<div><span>2</span></div>`)
|
||||
})
|
||||
})
|
||||
|
@ -69,7 +69,6 @@ export const SuspenseImpl = {
|
||||
anchor,
|
||||
parentComponent,
|
||||
isSVG,
|
||||
optimized,
|
||||
rendererInternals
|
||||
)
|
||||
}
|
||||
@ -121,8 +120,7 @@ function mountSuspense(
|
||||
null,
|
||||
parentComponent,
|
||||
suspense,
|
||||
isSVG,
|
||||
optimized
|
||||
isSVG
|
||||
)
|
||||
// now check if we have encountered any async deps
|
||||
if (suspense.deps > 0) {
|
||||
@ -135,8 +133,7 @@ function mountSuspense(
|
||||
anchor,
|
||||
parentComponent,
|
||||
null, // fallback tree will not have suspense context
|
||||
isSVG,
|
||||
optimized
|
||||
isSVG
|
||||
)
|
||||
setActiveBranch(suspense, vnode.ssFallback!)
|
||||
} else {
|
||||
@ -152,7 +149,6 @@ function patchSuspense(
|
||||
anchor: RendererNode | null,
|
||||
parentComponent: ComponentInternalInstance | null,
|
||||
isSVG: boolean,
|
||||
optimized: boolean,
|
||||
{ p: patch, um: unmount, o: { createElement } }: RendererInternals
|
||||
) {
|
||||
const suspense = (n2.suspense = n1.suspense)!
|
||||
@ -173,8 +169,7 @@ function patchSuspense(
|
||||
null,
|
||||
parentComponent,
|
||||
suspense,
|
||||
isSVG,
|
||||
optimized
|
||||
isSVG
|
||||
)
|
||||
if (suspense.deps <= 0) {
|
||||
suspense.resolve()
|
||||
@ -186,8 +181,7 @@ function patchSuspense(
|
||||
anchor,
|
||||
parentComponent,
|
||||
null, // fallback tree will not have suspense context
|
||||
isSVG,
|
||||
optimized
|
||||
isSVG
|
||||
)
|
||||
setActiveBranch(suspense, newFallback)
|
||||
}
|
||||
@ -220,8 +214,7 @@ function patchSuspense(
|
||||
null,
|
||||
parentComponent,
|
||||
suspense,
|
||||
isSVG,
|
||||
optimized
|
||||
isSVG
|
||||
)
|
||||
if (suspense.deps <= 0) {
|
||||
suspense.resolve()
|
||||
@ -233,8 +226,7 @@ function patchSuspense(
|
||||
anchor,
|
||||
parentComponent,
|
||||
null, // fallback tree will not have suspense context
|
||||
isSVG,
|
||||
optimized
|
||||
isSVG
|
||||
)
|
||||
setActiveBranch(suspense, newFallback)
|
||||
}
|
||||
@ -247,8 +239,7 @@ function patchSuspense(
|
||||
anchor,
|
||||
parentComponent,
|
||||
suspense,
|
||||
isSVG,
|
||||
optimized
|
||||
isSVG
|
||||
)
|
||||
// force resolve
|
||||
suspense.resolve(true)
|
||||
@ -261,8 +252,7 @@ function patchSuspense(
|
||||
null,
|
||||
parentComponent,
|
||||
suspense,
|
||||
isSVG,
|
||||
optimized
|
||||
isSVG
|
||||
)
|
||||
if (suspense.deps <= 0) {
|
||||
suspense.resolve()
|
||||
@ -279,8 +269,7 @@ function patchSuspense(
|
||||
anchor,
|
||||
parentComponent,
|
||||
suspense,
|
||||
isSVG,
|
||||
optimized
|
||||
isSVG
|
||||
)
|
||||
setActiveBranch(suspense, newBranch)
|
||||
} else {
|
||||
@ -300,8 +289,7 @@ function patchSuspense(
|
||||
null,
|
||||
parentComponent,
|
||||
suspense,
|
||||
isSVG,
|
||||
optimized
|
||||
isSVG
|
||||
)
|
||||
if (suspense.deps <= 0) {
|
||||
// incoming branch has no async deps, resolve now.
|
||||
@ -327,7 +315,6 @@ export interface SuspenseBoundary {
|
||||
parent: SuspenseBoundary | null
|
||||
parentComponent: ComponentInternalInstance | null
|
||||
isSVG: boolean
|
||||
optimized: boolean
|
||||
container: RendererElement
|
||||
hiddenContainer: RendererElement
|
||||
anchor: RendererNode | null
|
||||
@ -392,7 +379,6 @@ function createSuspenseBoundary(
|
||||
parent,
|
||||
parentComponent,
|
||||
isSVG,
|
||||
optimized,
|
||||
container,
|
||||
hiddenContainer,
|
||||
anchor,
|
||||
@ -499,8 +485,7 @@ function createSuspenseBoundary(
|
||||
activeBranch,
|
||||
parentComponent,
|
||||
container,
|
||||
isSVG,
|
||||
optimized
|
||||
isSVG
|
||||
} = suspense
|
||||
|
||||
// invoke @fallback event
|
||||
@ -522,8 +507,7 @@ function createSuspenseBoundary(
|
||||
anchor,
|
||||
parentComponent,
|
||||
null, // fallback tree will not have suspense context
|
||||
isSVG,
|
||||
optimized
|
||||
isSVG
|
||||
)
|
||||
setActiveBranch(suspense, fallbackVNode)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user