feat(runtime-dom): support using mount target innerHTML as template
This commit is contained in:
parent
ed29af7bea
commit
6a92bbd9c0
@ -18,7 +18,7 @@ export interface App<HostElement = any> {
|
|||||||
directive(name: string, directive: Directive): this
|
directive(name: string, directive: Directive): this
|
||||||
mount(
|
mount(
|
||||||
rootComponent: Component,
|
rootComponent: Component,
|
||||||
rootContainer: HostElement,
|
rootContainer: HostElement | string,
|
||||||
rootProps?: Data
|
rootProps?: Data
|
||||||
): ComponentPublicInstance
|
): ComponentPublicInstance
|
||||||
provide<T>(key: InjectionKey<T> | string, value: T): void
|
provide<T>(key: InjectionKey<T> | string, value: T): void
|
||||||
@ -141,7 +141,7 @@ export function createAppAPI<HostNode, HostElement>(
|
|||||||
|
|
||||||
mount(
|
mount(
|
||||||
rootComponent: Component,
|
rootComponent: Component,
|
||||||
rootContainer: string | HostElement,
|
rootContainer: HostElement,
|
||||||
rootProps?: Data
|
rootProps?: Data
|
||||||
): any {
|
): any {
|
||||||
if (!isMounted) {
|
if (!isMounted) {
|
||||||
|
@ -123,7 +123,7 @@ export interface RendererOptions<HostNode = any, HostElement = any> {
|
|||||||
|
|
||||||
export type RootRenderFunction<HostNode, HostElement> = (
|
export type RootRenderFunction<HostNode, HostElement> = (
|
||||||
vnode: VNode<HostNode, HostElement> | null,
|
vnode: VNode<HostNode, HostElement> | null,
|
||||||
dom: HostElement | string
|
dom: HostElement
|
||||||
) => void
|
) => void
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1858,19 +1858,12 @@ export function createRenderer<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function render(vnode: HostVNode | null, rawContainer: HostElement | string) {
|
const render: RootRenderFunction<
|
||||||
let container: any = rawContainer
|
HostNode,
|
||||||
if (isString(container)) {
|
HostElement & {
|
||||||
container = hostQuerySelector(container)
|
_vnode: HostVNode | null
|
||||||
if (!container) {
|
|
||||||
if (__DEV__) {
|
|
||||||
warn(
|
|
||||||
`Failed to locate root container: ` + `querySelector returned null.`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
> = (vnode, container) => {
|
||||||
if (vnode == null) {
|
if (vnode == null) {
|
||||||
if (container._vnode) {
|
if (container._vnode) {
|
||||||
unmount(container._vnode, null, null, true)
|
unmount(container._vnode, null, null, true)
|
||||||
|
@ -1,27 +1,54 @@
|
|||||||
import { createRenderer } from '@vue/runtime-core'
|
import { createRenderer, warn } from '@vue/runtime-core'
|
||||||
import { nodeOps } from './nodeOps'
|
import { nodeOps } from './nodeOps'
|
||||||
import { patchProp } from './patchProp'
|
import { patchProp } from './patchProp'
|
||||||
// Importing from the compiler, will be tree-shaken in prod
|
// Importing from the compiler, will be tree-shaken in prod
|
||||||
import { isHTMLTag, isSVGTag } from '@vue/compiler-dom'
|
import { isHTMLTag, isSVGTag } from '@vue/compiler-dom'
|
||||||
|
import { isFunction, isString } from '@vue/shared'
|
||||||
|
|
||||||
const { render, createApp } = createRenderer<Node, Element>({
|
const { render, createApp: baseCreateApp } = createRenderer<Node, Element>({
|
||||||
patchProp,
|
patchProp,
|
||||||
...nodeOps
|
...nodeOps
|
||||||
})
|
})
|
||||||
|
|
||||||
const wrappedCreateApp = () => {
|
const createApp = () => {
|
||||||
const app = createApp()
|
const app = baseCreateApp()
|
||||||
// inject `isNativeTag` dev only
|
|
||||||
Object.defineProperty(app.config, 'isNativeTag', {
|
if (__DEV__) {
|
||||||
value: (tag: string) => isHTMLTag(tag) || isSVGTag(tag),
|
// Inject `isNativeTag`
|
||||||
writable: false
|
// this is used for component name validation (dev only)
|
||||||
})
|
Object.defineProperty(app.config, 'isNativeTag', {
|
||||||
|
value: (tag: string) => isHTMLTag(tag) || isSVGTag(tag),
|
||||||
|
writable: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const mount = app.mount
|
||||||
|
app.mount = (component, container, props): any => {
|
||||||
|
if (isString(container)) {
|
||||||
|
container = document.querySelector(container)!
|
||||||
|
if (!container) {
|
||||||
|
__DEV__ &&
|
||||||
|
warn(`Failed to mount app: mount target selector returned null.`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
__RUNTIME_COMPILE__ &&
|
||||||
|
!isFunction(component) &&
|
||||||
|
!component.render &&
|
||||||
|
!component.template
|
||||||
|
) {
|
||||||
|
component.template = container.innerHTML
|
||||||
|
}
|
||||||
|
// clear content before mounting
|
||||||
|
container.innerHTML = ''
|
||||||
|
return mount(component, container, props)
|
||||||
|
}
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
const exportedCreateApp = __DEV__ ? wrappedCreateApp : createApp
|
export { render, createApp }
|
||||||
|
|
||||||
export { render, exportedCreateApp as createApp }
|
|
||||||
|
|
||||||
// DOM-only runtime helpers
|
// DOM-only runtime helpers
|
||||||
export {
|
export {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user