+111
-39
lines changedFilter options
+111
-39
lines changed Original file line number Diff line number Diff line change
@@ -626,6 +626,67 @@ 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 () => {
630
+
const Comp = {
631
+
render() {
632
+
return h('h1', 'Async component')
633
+
}
634
+
}
635
+
let serverResolve: any
636
+
let AsyncComp = defineAsyncComponent(
637
+
() =>
638
+
new Promise(r => {
639
+
serverResolve = r
640
+
})
641
+
)
642
+
643
+
const bol = ref(true)
644
+
const App = {
645
+
setup() {
646
+
onMounted(() => {
647
+
// change state, this makes updateComponent(AsyncComp) execute before
648
+
// the async component is resolved
649
+
bol.value = false
650
+
})
651
+
652
+
return () => {
653
+
return [bol.value ? 'hello' : 'world', h(AsyncComp)]
654
+
}
655
+
}
656
+
}
657
+
658
+
// server render
659
+
const htmlPromise = renderToString(h(App))
660
+
serverResolve(Comp)
661
+
const html = await htmlPromise
662
+
expect(html).toMatchInlineSnapshot(
663
+
`"<!--[-->hello<h1>Async component</h1><!--]-->"`
664
+
)
665
+
666
+
// hydration
667
+
let clientResolve: any
668
+
AsyncComp = defineAsyncComponent(
669
+
() =>
670
+
new Promise(r => {
671
+
clientResolve = r
672
+
})
673
+
)
674
+
675
+
const container = document.createElement('div')
676
+
container.innerHTML = html
677
+
createSSRApp(App).mount(container)
678
+
679
+
// resolve
680
+
clientResolve(Comp)
681
+
await new Promise(r => setTimeout(r))
682
+
683
+
// should be hydrated now
684
+
expect(`Hydration node mismatch`).not.toHaveBeenWarned()
685
+
expect(container.innerHTML).toMatchInlineSnapshot(
686
+
`"<!--[-->world<h1>Async component</h1><!--]-->"`
687
+
)
688
+
})
689
+
629
690
test('elements with camel-case in svg ', () => {
630
691
const { vnode, container } = mountWithHydration(
631
692
'<animateTransform></animateTransform>',
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ import {
8
8
VNodeHook
9
9
} from './vnode'
10
10
import { flushPostFlushCbs } from './scheduler'
11
-
import { ComponentOptions, ComponentInternalInstance } from './component'
11
+
import { ComponentInternalInstance } from './component'
12
12
import { invokeDirectiveHook } from './directives'
13
13
import { warn } from './warning'
14
14
import { PatchFlags, ShapeFlags, isReservedProp, isOn } from '@vue/shared'
@@ -178,24 +178,15 @@ export function createHydrationFunctions(
178
178
// on its sub-tree.
179
179
vnode.slotScopeIds = slotScopeIds
180
180
const container = parentNode(node)!
181
-
const hydrateComponent = () => {
182
-
mountComponent(
183
-
vnode,
184
-
container,
185
-
null,
186
-
parentComponent,
187
-
parentSuspense,
188
-
isSVGContainer(container),
189
-
optimized
190
-
)
191
-
}
192
-
// async component
193
-
const loadAsync = (vnode.type as ComponentOptions).__asyncLoader
194
-
if (loadAsync) {
195
-
loadAsync().then(hydrateComponent)
196
-
} else {
197
-
hydrateComponent()
198
-
}
181
+
mountComponent(
182
+
vnode,
183
+
container,
184
+
null,
185
+
parentComponent,
186
+
parentSuspense,
187
+
isSVGContainer(container),
188
+
optimized
189
+
)
199
190
// component may be async, so in the case of fragments we cannot rely
200
191
// on component's rendered output to determine the end of the fragment
201
192
// instead, we do a lookahead to find the end anchor node.
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ import {
16
16
} from './vnode'
17
17
import {
18
18
ComponentInternalInstance,
19
+
ComponentOptions,
19
20
createComponentInstance,
20
21
Data,
21
22
setupComponent
@@ -1430,31 +1431,50 @@ function baseCreateRenderer(
1430
1431
instance.emit('hook:beforeMount')
1431
1432
}
1432
1433
1433
-
// render
1434
-
if (__DEV__) {
1435
-
startMeasure(instance, `render`)
1436
-
}
1437
-
const subTree = (instance.subTree = renderComponentRoot(instance))
1438
-
if (__DEV__) {
1439
-
endMeasure(instance, `render`)
1440
-
}
1441
-
1442
1434
if (el && hydrateNode) {
1435
+
// vnode has adopted host node - perform hydration instead of mount.
1436
+
const hydrateSubTree = () => {
1437
+
if (__DEV__) {
1438
+
startMeasure(instance, `render`)
1439
+
}
1440
+
instance.subTree = renderComponentRoot(instance)
1441
+
if (__DEV__) {
1442
+
endMeasure(instance, `render`)
1443
+
}
1444
+
if (__DEV__) {
1445
+
startMeasure(instance, `hydrate`)
1446
+
}
1447
+
hydrateNode!(
1448
+
el as Node,
1449
+
instance.subTree,
1450
+
instance,
1451
+
parentSuspense,
1452
+
null
1453
+
)
1454
+
if (__DEV__) {
1455
+
endMeasure(instance, `hydrate`)
1456
+
}
1457
+
}
1458
+
1459
+
if (isAsyncWrapper(initialVNode)) {
1460
+
(initialVNode.type as ComponentOptions).__asyncLoader!().then(
1461
+
// note: we are moving the render call into an async callback,
1462
+
// which means it won't track dependencies - but it's ok because
1463
+
// a server-rendered async wrapper is already in resolved state
1464
+
// and it will never need to change.
1465
+
hydrateSubTree
1466
+
)
1467
+
} else {
1468
+
hydrateSubTree()
1469
+
}
1470
+
} else {
1443
1471
if (__DEV__) {
1444
-
startMeasure(instance, `hydrate`)
1472
+
startMeasure(instance, `render`)
1445
1473
}
1446
-
// vnode has adopted host node - perform hydration instead of mount.
1447
-
hydrateNode(
1448
-
initialVNode.el as Node,
1449
-
subTree,
1450
-
instance,
1451
-
parentSuspense,
1452
-
null
1453
-
)
1474
+
const subTree = (instance.subTree = renderComponentRoot(instance))
1454
1475
if (__DEV__) {
1455
-
endMeasure(instance, `hydrate`)
1476
+
endMeasure(instance, `render`)
1456
1477
}
1457
-
} else {
1458
1478
if (__DEV__) {
1459
1479
startMeasure(instance, `patch`)
1460
1480
}
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