fix(ssr): ensure app can be unmounted when created with createSSRApp() (#5992)
fix #5990
This commit is contained in:
parent
160d5df34a
commit
d4d3319c1b
@ -922,7 +922,9 @@ describe('SSR hydration', () => {
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const { container, vnode } = mountWithHydration('<!--[--><!--]-->', () => h(Comp))
|
const { container, vnode } = mountWithHydration('<!--[--><!--]-->', () =>
|
||||||
|
h(Comp)
|
||||||
|
)
|
||||||
expect(container.childNodes.length).toBe(3)
|
expect(container.childNodes.length).toBe(3)
|
||||||
const text = container.childNodes[1]
|
const text = container.childNodes[1]
|
||||||
expect(text.nodeType).toBe(3)
|
expect(text.nodeType).toBe(3)
|
||||||
@ -931,6 +933,33 @@ describe('SSR hydration', () => {
|
|||||||
expect((vnode as any).component?.subTree.children[0].el).toBe(text)
|
expect((vnode as any).component?.subTree.children[0].el).toBe(text)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('app.unmount()', async () => {
|
||||||
|
const container = document.createElement('DIV')
|
||||||
|
container.innerHTML = '<button></button>'
|
||||||
|
const App = defineComponent({
|
||||||
|
setup(_, { expose }) {
|
||||||
|
const count = ref(0)
|
||||||
|
|
||||||
|
expose({ count })
|
||||||
|
|
||||||
|
return () =>
|
||||||
|
h('button', {
|
||||||
|
onClick: () => count.value++
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const app = createSSRApp(App)
|
||||||
|
const vm = app.mount(container)
|
||||||
|
await nextTick()
|
||||||
|
expect((container as any)._vnode).toBeDefined()
|
||||||
|
// @ts-expect-error - expose()'d properties are not available on vm type
|
||||||
|
expect(vm.count).toBe(0)
|
||||||
|
|
||||||
|
app.unmount()
|
||||||
|
expect((container as any)._vnode).toBe(null)
|
||||||
|
})
|
||||||
|
|
||||||
describe('mismatch handling', () => {
|
describe('mismatch handling', () => {
|
||||||
test('text node', () => {
|
test('text node', () => {
|
||||||
const { container } = mountWithHydration(`foo`, () => 'bar')
|
const { container } = mountWithHydration(`foo`, () => 'bar')
|
||||||
|
@ -27,7 +27,7 @@ import { isAsyncWrapper } from './apiAsyncComponent'
|
|||||||
|
|
||||||
export type RootHydrateFunction = (
|
export type RootHydrateFunction = (
|
||||||
vnode: VNode<Node, Element>,
|
vnode: VNode<Node, Element>,
|
||||||
container: Element | ShadowRoot
|
container: (Element | ShadowRoot) & { _vnode?: VNode }
|
||||||
) => void
|
) => void
|
||||||
|
|
||||||
const enum DOMNodeTypes {
|
const enum DOMNodeTypes {
|
||||||
@ -75,11 +75,13 @@ export function createHydrationFunctions(
|
|||||||
)
|
)
|
||||||
patch(null, vnode, container)
|
patch(null, vnode, container)
|
||||||
flushPostFlushCbs()
|
flushPostFlushCbs()
|
||||||
|
container._vnode = vnode
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hasMismatch = false
|
hasMismatch = false
|
||||||
hydrateNode(container.firstChild!, vnode, null, null, null)
|
hydrateNode(container.firstChild!, vnode, null, null, null)
|
||||||
flushPostFlushCbs()
|
flushPostFlushCbs()
|
||||||
|
container._vnode = vnode
|
||||||
if (hasMismatch && !__TEST__) {
|
if (hasMismatch && !__TEST__) {
|
||||||
// this error should show up in production
|
// this error should show up in production
|
||||||
console.error(`Hydration completed but contains mismatches.`)
|
console.error(`Hydration completed but contains mismatches.`)
|
||||||
|
Loading…
Reference in New Issue
Block a user