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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user