( app: App, context: AppContext, render: RootRenderFunction, )
| 450 | } |
| 451 | |
| 452 | function installCompatMount( |
| 453 | app: App, |
| 454 | context: AppContext, |
| 455 | render: RootRenderFunction, |
| 456 | ) { |
| 457 | let isMounted = false |
| 458 | |
| 459 | /** |
| 460 | * Vue 2 supports the behavior of creating a component instance but not |
| 461 | * mounting it, which is no longer possible in Vue 3 - this internal |
| 462 | * function simulates that behavior. |
| 463 | */ |
| 464 | app._createRoot = options => { |
| 465 | const component = app._component |
| 466 | const vnode = createVNode(component, options.propsData || null) |
| 467 | vnode.appContext = context |
| 468 | |
| 469 | const hasNoRender = |
| 470 | !isFunction(component) && !component.render && !component.template |
| 471 | const emptyRender = () => {} |
| 472 | |
| 473 | // create root instance |
| 474 | const instance = createComponentInstance(vnode, null, null) |
| 475 | // suppress "missing render fn" warning since it can't be determined |
| 476 | // until $mount is called |
| 477 | if (hasNoRender) { |
| 478 | instance.render = emptyRender |
| 479 | } |
| 480 | setupComponent(instance) |
| 481 | vnode.component = instance |
| 482 | vnode.isCompatRoot = true |
| 483 | |
| 484 | // $mount & $destroy |
| 485 | // these are defined on ctx and picked up by the $mount/$destroy |
| 486 | // public property getters on the instance proxy. |
| 487 | // Note: the following assumes DOM environment since the compat build |
| 488 | // only targets web. It essentially includes logic for app.mount from |
| 489 | // both runtime-core AND runtime-dom. |
| 490 | instance.ctx._compat_mount = (selectorOrEl?: string | Element) => { |
| 491 | if (isMounted) { |
| 492 | __DEV__ && warn(`Root instance is already mounted.`) |
| 493 | return |
| 494 | } |
| 495 | |
| 496 | let container: Element |
| 497 | if (typeof selectorOrEl === 'string') { |
| 498 | // eslint-disable-next-line |
| 499 | const result = document.querySelector(selectorOrEl) |
| 500 | if (!result) { |
| 501 | __DEV__ && |
| 502 | warn( |
| 503 | `Failed to mount root instance: selector "${selectorOrEl}" returned null.`, |
| 504 | ) |
| 505 | return |
| 506 | } |
| 507 | container = result |
| 508 | } else { |
| 509 | // eslint-disable-next-line |
no test coverage detected