mirror of https://github.com/vuejs/core.git
fix(hydration): the component vnode's el should be updated when a mismatch occurs. (#12255)
close #12253
This commit is contained in:
parent
352bc88c1b
commit
a20a4cb36a
|
@ -21,6 +21,7 @@ import {
|
||||||
h,
|
h,
|
||||||
nextTick,
|
nextTick,
|
||||||
onMounted,
|
onMounted,
|
||||||
|
onServerPrefetch,
|
||||||
openBlock,
|
openBlock,
|
||||||
reactive,
|
reactive,
|
||||||
ref,
|
ref,
|
||||||
|
@ -518,6 +519,45 @@ describe('SSR hydration', () => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('with data-allow-mismatch component when using onServerPrefetch', async () => {
|
||||||
|
const Comp = {
|
||||||
|
template: `
|
||||||
|
<div>Comp2</div>
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
let foo: any
|
||||||
|
const App = {
|
||||||
|
setup() {
|
||||||
|
const flag = ref(true)
|
||||||
|
foo = () => {
|
||||||
|
flag.value = false
|
||||||
|
}
|
||||||
|
onServerPrefetch(() => (flag.value = false))
|
||||||
|
return { flag }
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
Comp,
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<span data-allow-mismatch>
|
||||||
|
<Comp v-if="flag"></Comp>
|
||||||
|
</span>
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
// hydrate
|
||||||
|
const container = document.createElement('div')
|
||||||
|
container.innerHTML = await renderToString(h(App))
|
||||||
|
createSSRApp(App).mount(container)
|
||||||
|
expect(container.innerHTML).toBe(
|
||||||
|
'<span data-allow-mismatch=""><div>Comp2</div></span>',
|
||||||
|
)
|
||||||
|
foo()
|
||||||
|
await nextTick()
|
||||||
|
expect(container.innerHTML).toBe(
|
||||||
|
'<span data-allow-mismatch=""><!--v-if--></span>',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
test('Teleport unmount (full integration)', async () => {
|
test('Teleport unmount (full integration)', async () => {
|
||||||
const Comp1 = {
|
const Comp1 = {
|
||||||
template: `
|
template: `
|
||||||
|
|
|
@ -41,6 +41,7 @@ import {
|
||||||
import type { TeleportImpl, TeleportVNode } from './components/Teleport'
|
import type { TeleportImpl, TeleportVNode } from './components/Teleport'
|
||||||
import { isAsyncWrapper } from './apiAsyncComponent'
|
import { isAsyncWrapper } from './apiAsyncComponent'
|
||||||
import { isReactive } from '@vue/reactivity'
|
import { isReactive } from '@vue/reactivity'
|
||||||
|
import { updateHOCHostEl } from './componentRenderUtils'
|
||||||
|
|
||||||
export type RootHydrateFunction = (
|
export type RootHydrateFunction = (
|
||||||
vnode: VNode<Node, Element>,
|
vnode: VNode<Node, Element>,
|
||||||
|
@ -716,6 +717,11 @@ export function createHydrationFunctions(
|
||||||
getContainerType(container),
|
getContainerType(container),
|
||||||
slotScopeIds,
|
slotScopeIds,
|
||||||
)
|
)
|
||||||
|
// the component vnode's el should be updated when a mismatch occurs.
|
||||||
|
if (parentComponent) {
|
||||||
|
parentComponent.vnode.el = vnode.el
|
||||||
|
updateHOCHostEl(parentComponent, vnode.el)
|
||||||
|
}
|
||||||
return next
|
return next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue