+77
-3
lines changedFilter options
+77
-3
lines changed Original file line number Diff line number Diff line change
@@ -626,7 +626,7 @@ describe('SSR hydration', () => {
626
626
expect(spy).toHaveBeenCalled()
627
627
})
628
628
629
-
test('execute the updateComponent(AsyncComponentWrapper) before the async component is resolved', async () => {
629
+
test('update async wrapper before resolve', async () => {
630
630
const Comp = {
631
631
render() {
632
632
return h('h1', 'Async component')
@@ -687,6 +687,57 @@ describe('SSR hydration', () => {
687
687
)
688
688
})
689
689
690
+
// #3787
691
+
test('unmount async wrapper before load', async () => {
692
+
let resolve: any
693
+
const AsyncComp = defineAsyncComponent(
694
+
() =>
695
+
new Promise(r => {
696
+
resolve = r
697
+
})
698
+
)
699
+
700
+
const show = ref(true)
701
+
const root = document.createElement('div')
702
+
root.innerHTML = '<div><div>async</div></div>'
703
+
704
+
createSSRApp({
705
+
render() {
706
+
return h('div', [show.value ? h(AsyncComp) : h('div', 'hi')])
707
+
}
708
+
}).mount(root)
709
+
710
+
show.value = false
711
+
await nextTick()
712
+
expect(root.innerHTML).toBe('<div><div>hi</div></div>')
713
+
resolve({})
714
+
})
715
+
716
+
test('unmount async wrapper before load (fragment)', async () => {
717
+
let resolve: any
718
+
const AsyncComp = defineAsyncComponent(
719
+
() =>
720
+
new Promise(r => {
721
+
resolve = r
722
+
})
723
+
)
724
+
725
+
const show = ref(true)
726
+
const root = document.createElement('div')
727
+
root.innerHTML = '<div><!--[-->async<!--]--></div>'
728
+
729
+
createSSRApp({
730
+
render() {
731
+
return h('div', [show.value ? h(AsyncComp) : h('div', 'hi')])
732
+
}
733
+
}).mount(root)
734
+
735
+
show.value = false
736
+
await nextTick()
737
+
expect(root.innerHTML).toBe('<div><div>hi</div></div>')
738
+
resolve({})
739
+
})
740
+
690
741
test('elements with camel-case in svg ', () => {
691
742
const { vnode, container } = mountWithHydration(
692
743
'<animateTransform></animateTransform>',
Original file line number Diff line number Diff line change
@@ -5,7 +5,9 @@ import {
5
5
Comment,
6
6
Static,
7
7
Fragment,
8
-
VNodeHook
8
+
VNodeHook,
9
+
createVNode,
10
+
createTextVNode
9
11
} from './vnode'
10
12
import { flushPostFlushCbs } from './scheduler'
11
13
import { ComponentInternalInstance } from './component'
@@ -19,6 +21,7 @@ import {
19
21
queueEffectWithSuspense
20
22
} from './components/Suspense'
21
23
import { TeleportImpl, TeleportVNode } from './components/Teleport'
24
+
import { isAsyncWrapper } from './apiAsyncComponent'
22
25
23
26
export type RootHydrateFunction = (
24
27
vnode: VNode<Node, Element>,
@@ -187,12 +190,32 @@ export function createHydrationFunctions(
187
190
isSVGContainer(container),
188
191
optimized
189
192
)
193
+
190
194
// component may be async, so in the case of fragments we cannot rely
191
195
// on component's rendered output to determine the end of the fragment
192
196
// instead, we do a lookahead to find the end anchor node.
193
197
nextNode = isFragmentStart
194
198
? locateClosingAsyncAnchor(node)
195
199
: nextSibling(node)
200
+
201
+
// #3787
202
+
// if component is async, it may get moved / unmounted before its
203
+
// inner component is loaded, so we need to give it a placeholder
204
+
// vnode that matches its adopted DOM.
205
+
if (isAsyncWrapper(vnode)) {
206
+
let subTree
207
+
if (isFragmentStart) {
208
+
subTree = createVNode(Fragment)
209
+
subTree.anchor = nextNode
210
+
? nextNode.previousSibling
211
+
: container.lastChild
212
+
} else {
213
+
subTree =
214
+
node.nodeType === 3 ? createTextVNode('') : createVNode('div')
215
+
}
216
+
subTree.el = node
217
+
vnode.component!.subTree = subTree
218
+
}
196
219
} else if (shapeFlag & ShapeFlags.TELEPORT) {
197
220
if (domType !== DOMNodeTypes.COMMENT) {
198
221
nextNode = onMismatch()
Original file line number Diff line number Diff line change
@@ -1462,7 +1462,7 @@ function baseCreateRenderer(
1462
1462
// which means it won't track dependencies - but it's ok because
1463
1463
// a server-rendered async wrapper is already in resolved state
1464
1464
// and it will never need to change.
1465
-
hydrateSubTree
1465
+
() => !instance.isUnmounted && hydrateSubTree()
1466
1466
)
1467
1467
} else {
1468
1468
hydrateSubTree()
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4