refactor: adjust createApp related API signatures

BREAKING CHANGE: `createApp` API has been adjusted.

  - `createApp()` now accepts the root component, and optionally a props
  object to pass to the root component.
  - `app.mount()` now accepts a single argument (the root container)
  - `app.unmount()` no longer requires arguments.

  New behavior looks like the following:

  ``` js
  const app = createApp(RootComponent)
  app.mount('#app')
  app.unmount()
  ```
This commit is contained in:
Evan You
2020-01-23 15:05:38 -05:00
parent eacd390992
commit c07751fd36
25 changed files with 276 additions and 326 deletions

View File

@@ -16,16 +16,11 @@ export interface App<HostElement = any> {
component(name: string, component: Component): this
directive(name: string): Directive | undefined
directive(name: string, directive: Directive): this
mount(
rootComponent:
| Component
// for compatibility with defineComponent() return types
| { new (): ComponentPublicInstance<any, any, any, any, any> },
rootContainer: HostElement | string,
rootProps?: Data
): ComponentPublicInstance
mount(rootContainer: HostElement | string): ComponentPublicInstance
unmount(rootContainer: HostElement | string): void
provide<T>(key: InjectionKey<T> | string, value: T): this
rootComponent: Component
rootContainer: HostElement | null
}
export interface AppConfig {
@@ -79,16 +74,30 @@ export function createAppContext(): AppContext {
}
}
export type CreateAppFunction<HostElement> = (
rootComponent:
| Component
// for compatibility with defineComponent() return types
| { new (): ComponentPublicInstance<any, any, any, any, any> },
rootProps?: Data | null
) => App<HostElement>
export function createAppAPI<HostNode, HostElement>(
render: RootRenderFunction<HostNode, HostElement>
): () => App<HostElement> {
return function createApp(): App {
): CreateAppFunction<HostElement> {
return function createApp(
rootComponent: Component,
rootProps?: Data | null
): App {
const context = createAppContext()
const installedPlugins = new Set()
let isMounted = false
const app: App = {
rootComponent,
rootContainer: null,
get config() {
return context.config
},
@@ -165,11 +174,7 @@ export function createAppAPI<HostNode, HostElement>(
return app
},
mount(
rootComponent: Component,
rootContainer: HostElement,
rootProps?: Data | null
): any {
mount(rootContainer: HostElement): any {
if (!isMounted) {
if (rootProps != null && !isObject(rootProps)) {
__DEV__ &&
@@ -190,6 +195,7 @@ export function createAppAPI<HostNode, HostElement>(
render(vnode, rootContainer)
isMounted = true
app.rootContainer = rootContainer
return vnode.component!.proxy
} else if (__DEV__) {
warn(
@@ -198,8 +204,12 @@ export function createAppAPI<HostNode, HostElement>(
}
},
unmount(rootContainer: HostElement) {
render(null, rootContainer)
unmount() {
if (isMounted) {
render(null, app.rootContainer!)
} else if (__DEV__) {
warn(`Cannot unmount an app that is not mounted.`)
}
},
provide(key, value) {

View File

@@ -99,7 +99,13 @@ export { registerRuntimeCompiler } from './component'
// Types -----------------------------------------------------------------------
export { App, AppConfig, AppContext, Plugin } from './apiCreateApp'
export {
App,
AppConfig,
AppContext,
Plugin,
CreateAppFunction
} from './apiCreateApp'
export { VNode, VNodeTypes, VNodeProps } from './vnode'
export {
Component,

View File

@@ -46,7 +46,7 @@ import { ShapeFlags } from './shapeFlags'
import { pushWarningContext, popWarningContext, warn } from './warning'
import { invokeDirectiveHook } from './directives'
import { ComponentPublicInstance } from './componentProxy'
import { App, createAppAPI } from './apiCreateApp'
import { createAppAPI, CreateAppFunction } from './apiCreateApp'
import {
SuspenseBoundary,
queueEffectWithSuspense,
@@ -174,7 +174,7 @@ export function createRenderer<
options: RendererOptions<HostNode, HostElement>
): {
render: RootRenderFunction<HostNode, HostElement>
createApp: () => App<HostElement>
createApp: CreateAppFunction<HostElement>
} {
type HostVNode = VNode<HostNode, HostElement>
type HostVNodeChildren = VNodeChildren<HostNode, HostElement>