wip: progress
This commit is contained in:
parent
40e3dd28e1
commit
53b8127a9c
@ -15,8 +15,7 @@ import { RootHydrateFunction } from './hydration'
|
||||
import { devtoolsInitApp, devtoolsUnmountApp } from './devtools'
|
||||
import { isFunction, NO, isObject } from '@vue/shared'
|
||||
import { version } from '.'
|
||||
import { installCompatMount } from './compat/globalMount'
|
||||
import { installLegacyConfigTraps } from './compat/globalConfig'
|
||||
import { installCompatMount, installLegacyConfigTraps } from './compat/global'
|
||||
|
||||
export interface App<HostElement = any> {
|
||||
version: string
|
||||
@ -307,7 +306,7 @@ export function createAppAPI<HostElement>(
|
||||
|
||||
if (__COMPAT__) {
|
||||
installCompatMount(app, context, render, hydrate)
|
||||
installLegacyConfigTraps(app.config)
|
||||
if (__DEV__) installLegacyConfigTraps(app.config)
|
||||
}
|
||||
|
||||
return app
|
||||
|
@ -1,15 +1,22 @@
|
||||
import { isRuntimeOnly } from '../component'
|
||||
|
||||
export const enum DeprecationTypes {
|
||||
DOM_TEMPLATE_MOUNT,
|
||||
$MOUNT,
|
||||
$DESTROY,
|
||||
|
||||
CONFIG_SILENT,
|
||||
CONFIG_DEVTOOLS,
|
||||
CONFIG_KEY_CODES,
|
||||
CONFIG_PRODUCTION_TIP,
|
||||
CONFIG_IGNORED_ELEMENTS
|
||||
CONFIG_IGNORED_ELEMENTS,
|
||||
|
||||
GLOBAL_PROTOTYPE,
|
||||
GLOBAL_SET,
|
||||
GLOBAL_DELETE,
|
||||
GLOBAL_OBSERVABLE,
|
||||
GLOBAL_DOM_TEMPLATE_MOUNT,
|
||||
|
||||
INSTANCE_SET,
|
||||
INSTANCE_DELETE,
|
||||
INSTANCE_MOUNT,
|
||||
INSTANCE_DESTROY
|
||||
}
|
||||
|
||||
type DeprecationData = {
|
||||
@ -18,26 +25,6 @@ type DeprecationData = {
|
||||
}
|
||||
|
||||
const deprecations: Record<DeprecationTypes, DeprecationData> = {
|
||||
[DeprecationTypes.DOM_TEMPLATE_MOUNT]: {
|
||||
message:
|
||||
`Vue detected directives on the mount container. ` +
|
||||
`In Vue 3, the container is no longer considered part of the template ` +
|
||||
`and will not be processed/replaced.`,
|
||||
link: `https://v3.vuejs.org/guide/migration/mount-changes.html`
|
||||
},
|
||||
|
||||
[DeprecationTypes.$MOUNT]: {
|
||||
message:
|
||||
`vm.$mount() has been removed. ` +
|
||||
`Use createApp(RootComponent).mount() instead.`,
|
||||
link: `https://v3.vuejs.org/guide/migration/global-api.html#mounting-app-instance`
|
||||
},
|
||||
|
||||
[DeprecationTypes.$DESTROY]: {
|
||||
message: `vm.$destroy() has been removed. Use app.unmount() instead.`,
|
||||
link: `https://v3.vuejs.org/api/application-api.html#unmount`
|
||||
},
|
||||
|
||||
[DeprecationTypes.CONFIG_SILENT]: {
|
||||
message:
|
||||
`config.silent has been removed because it is not good practice to ` +
|
||||
@ -75,6 +62,64 @@ const deprecations: Record<DeprecationTypes, DeprecationData> = {
|
||||
return msg
|
||||
},
|
||||
link: `https://v3.vuejs.org/guide/migration/global-api.html#config-ignoredelements-is-now-config-iscustomelement`
|
||||
},
|
||||
|
||||
[DeprecationTypes.GLOBAL_PROTOTYPE]: {
|
||||
message:
|
||||
`Vue.prototype is no longer available in Vue 3. ` +
|
||||
`Use config.globalProperties instead.`,
|
||||
link: `https://v3.vuejs.org/guide/migration/global-api.html#vue-prototype-replaced-by-config-globalproperties`
|
||||
},
|
||||
|
||||
[DeprecationTypes.GLOBAL_SET]: {
|
||||
message:
|
||||
`Vue.set() has been removed as it is no longer needed in Vue 3. ` +
|
||||
`Simply use native JavaScript mutations.`
|
||||
},
|
||||
|
||||
[DeprecationTypes.GLOBAL_DELETE]: {
|
||||
message:
|
||||
`Vue.delete() has been removed as it is no longer needed in Vue 3. ` +
|
||||
`Simply use native JavaScript mutations.`
|
||||
},
|
||||
|
||||
[DeprecationTypes.GLOBAL_OBSERVABLE]: {
|
||||
message:
|
||||
`Vue.observable() has been removed. ` +
|
||||
`Use \`import { reactive } from "vue"\` from Composition API instead.`,
|
||||
link: `https://v3.vuejs.org/api/basic-reactivity.html`
|
||||
},
|
||||
|
||||
[DeprecationTypes.GLOBAL_DOM_TEMPLATE_MOUNT]: {
|
||||
message:
|
||||
`Vue detected directives on the mount container. ` +
|
||||
`In Vue 3, the container is no longer considered part of the template ` +
|
||||
`and will not be processed/replaced.`,
|
||||
link: `https://v3.vuejs.org/guide/migration/mount-changes.html`
|
||||
},
|
||||
|
||||
[DeprecationTypes.INSTANCE_SET]: {
|
||||
message:
|
||||
`vm.$set() has been removed as it is no longer needed in Vue 3. ` +
|
||||
`Simply use native JavaScript mutations.`
|
||||
},
|
||||
|
||||
[DeprecationTypes.INSTANCE_DELETE]: {
|
||||
message:
|
||||
`vm.$delete() has been removed as it is no longer needed in Vue 3. ` +
|
||||
`Simply use native JavaScript mutations.`
|
||||
},
|
||||
|
||||
[DeprecationTypes.INSTANCE_MOUNT]: {
|
||||
message:
|
||||
`The global app boostrapping API has changed: vm.$mount() and the "el" ` +
|
||||
`option have been removed. Use createApp(RootComponent).mount() instead.`,
|
||||
link: `https://v3.vuejs.org/guide/migration/global-api.html#mounting-app-instance`
|
||||
},
|
||||
|
||||
[DeprecationTypes.INSTANCE_DESTROY]: {
|
||||
message: `vm.$destroy() has been removed. Use app.unmount() instead.`,
|
||||
link: `https://v3.vuejs.org/api/application-api.html#unmount`
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,32 @@
|
||||
import { reactive } from '@vue/reactivity'
|
||||
import { extend } from '@vue/shared'
|
||||
import { createApp } from '../../../runtime-dom/src'
|
||||
import { App, AppConfig, Plugin } from '../apiCreateApp'
|
||||
import { isFunction } from '@vue/shared'
|
||||
import { warn } from '../warning'
|
||||
import { cloneVNode, createVNode } from '../vnode'
|
||||
import { RootRenderFunction } from '../renderer'
|
||||
import { RootHydrateFunction } from '../hydration'
|
||||
import {
|
||||
App,
|
||||
AppConfig,
|
||||
AppContext,
|
||||
CreateAppFunction,
|
||||
Plugin
|
||||
} from '../apiCreateApp'
|
||||
import { defineComponent } from '../apiDefineComponent'
|
||||
import { Component, ComponentOptions, isRuntimeOnly } from '../component'
|
||||
import {
|
||||
Component,
|
||||
ComponentOptions,
|
||||
createComponentInstance,
|
||||
finishComponentSetup,
|
||||
isRuntimeOnly,
|
||||
setupComponent
|
||||
} from '../component'
|
||||
import { RenderFunction } from '../componentOptions'
|
||||
import { ComponentPublicInstance } from '../componentPublicInstance'
|
||||
import { devtoolsInitApp } from '../devtools'
|
||||
import { Directive } from '../directives'
|
||||
import { nextTick } from '../scheduler'
|
||||
import { warnDeprecation, DeprecationTypes } from './deprecations'
|
||||
import { version } from '..'
|
||||
|
||||
/**
|
||||
* @deprecated the default `Vue` export has been removed in Vue 3. The type for
|
||||
@ -21,7 +40,7 @@ export type CompatVue = Pick<App, 'version' | 'component' | 'directive'> & {
|
||||
new (options?: ComponentOptions): ComponentPublicInstance
|
||||
|
||||
version: string
|
||||
config: AppConfig
|
||||
config: AppConfig & LegacyConfig
|
||||
|
||||
extend: typeof defineComponent
|
||||
nextTick: typeof nextTick
|
||||
@ -54,10 +73,40 @@ export type CompatVue = Pick<App, 'version' | 'component' | 'directive'> & {
|
||||
filter(name: string, arg: any): null
|
||||
}
|
||||
|
||||
// legacy config warnings
|
||||
export type LegacyConfig = {
|
||||
/**
|
||||
* @deprecated `config.silent` option has been removed
|
||||
*/
|
||||
silent?: boolean
|
||||
/**
|
||||
* @deprecated use __VUE_PROD_DEVTOOLS__ compile-time feature flag instead
|
||||
* https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags
|
||||
*/
|
||||
devtools?: boolean
|
||||
/**
|
||||
* @deprecated use `config.isCustomElement` instead
|
||||
* https://v3.vuejs.org/guide/migration/global-api.html#config-ignoredelements-is-now-config-iscustomelement
|
||||
*/
|
||||
ignoredElements?: (string | RegExp)[]
|
||||
/**
|
||||
* @deprecated
|
||||
* https://v3.vuejs.org/guide/migration/keycode-modifiers.html
|
||||
*/
|
||||
keyCodes?: Record<string, number | number[]>
|
||||
/**
|
||||
* @deprecated
|
||||
* https://v3.vuejs.org/guide/migration/global-api.html#config-productiontip-removed
|
||||
*/
|
||||
productionTip?: boolean
|
||||
}
|
||||
|
||||
export let isCopyingConfig = false
|
||||
|
||||
// Legacy global Vue constructor
|
||||
export function createCompatVue(): CompatVue {
|
||||
export function createCompatVue(
|
||||
createApp: CreateAppFunction<Element>
|
||||
): CompatVue {
|
||||
if (!__COMPAT__) {
|
||||
// @ts-ignore this function will never be called in non-compat mode
|
||||
return
|
||||
@ -86,9 +135,16 @@ export function createCompatVue(): CompatVue {
|
||||
isCopyingConfig = false
|
||||
|
||||
// copy prototype augmentations as config.globalProperties
|
||||
let hasPrototypeAugmentations = false
|
||||
for (const key in Ctor.prototype) {
|
||||
if (key !== 'constructor') {
|
||||
hasPrototypeAugmentations = true
|
||||
}
|
||||
app.config.globalProperties[key] = Ctor.prototype[key]
|
||||
}
|
||||
if (hasPrototypeAugmentations) {
|
||||
__DEV__ && warnDeprecation(DeprecationTypes.GLOBAL_PROTOTYPE)
|
||||
}
|
||||
|
||||
const vm = app._createRoot!(options)
|
||||
if (options.el) {
|
||||
@ -124,15 +180,21 @@ export function createCompatVue(): CompatVue {
|
||||
Vue.nextTick = nextTick
|
||||
|
||||
Vue.set = (target, key, value) => {
|
||||
// TODO deprecation warnings
|
||||
__DEV__ && warnDeprecation(DeprecationTypes.GLOBAL_SET)
|
||||
target[key] = value
|
||||
}
|
||||
|
||||
Vue.delete = (target, key) => {
|
||||
// TODO deprecation warnings
|
||||
__DEV__ && warnDeprecation(DeprecationTypes.GLOBAL_DELETE)
|
||||
delete target[key]
|
||||
}
|
||||
// TODO wrap with deprecation warning
|
||||
Vue.observable = reactive
|
||||
|
||||
Vue.observable = __DEV__
|
||||
? (target: any) => {
|
||||
warnDeprecation(DeprecationTypes.GLOBAL_OBSERVABLE)
|
||||
return reactive(target)
|
||||
}
|
||||
: reactive
|
||||
|
||||
Vue.use = (p, ...options) => {
|
||||
singletonApp.use(p, ...options)
|
||||
@ -169,3 +231,156 @@ export function createCompatVue(): CompatVue {
|
||||
|
||||
return Vue
|
||||
}
|
||||
|
||||
export function installCompatMount(
|
||||
app: App,
|
||||
context: AppContext,
|
||||
render: RootRenderFunction,
|
||||
hydrate?: RootHydrateFunction
|
||||
) {
|
||||
let isMounted = false
|
||||
|
||||
/**
|
||||
* Vue 2 supports the behavior of creating a component instance but not
|
||||
* mounting it, which is no longer possible in Vue 3 - this internal
|
||||
* function simulates that behavior.
|
||||
*/
|
||||
app._createRoot = options => {
|
||||
const component = app._component
|
||||
const vnode = createVNode(component, options.propsData || null)
|
||||
vnode.appContext = context
|
||||
|
||||
const hasNoRender =
|
||||
!isFunction(component) && !component.render && !component.template
|
||||
const emptyRender = () => {}
|
||||
|
||||
// create root instance
|
||||
const instance = createComponentInstance(vnode, null, null)
|
||||
// suppress "missing render fn" warning since it can't be determined
|
||||
// until $mount is called
|
||||
if (hasNoRender) {
|
||||
instance.render = emptyRender
|
||||
}
|
||||
setupComponent(instance, __NODE_JS__)
|
||||
vnode.component = instance
|
||||
|
||||
// $mount & $destroy
|
||||
// these are defined on ctx and picked up by the $mount/$destroy
|
||||
// public property getters on the instance proxy.
|
||||
// Note: the following assumes DOM environment since the compat build
|
||||
// only targets web. It essentially includes logic for app.mount from
|
||||
// both runtime-core AND runtime-dom.
|
||||
instance.ctx._compat_mount = (selectorOrEl: string | Element) => {
|
||||
if (isMounted) {
|
||||
__DEV__ && warn(`Root instance is already mounted.`)
|
||||
return
|
||||
}
|
||||
|
||||
let container: Element
|
||||
if (typeof selectorOrEl === 'string') {
|
||||
// eslint-disable-next-line
|
||||
const result = document.querySelector(selectorOrEl)
|
||||
if (!result) {
|
||||
__DEV__ &&
|
||||
warn(
|
||||
`Failed to mount root instance: selector "${selectorOrEl}" returned null.`
|
||||
)
|
||||
return
|
||||
}
|
||||
container = result
|
||||
} else {
|
||||
if (!selectorOrEl) {
|
||||
__DEV__ &&
|
||||
warn(
|
||||
`Failed to mount root instance: invalid mount target ${selectorOrEl}.`
|
||||
)
|
||||
return
|
||||
}
|
||||
container = selectorOrEl
|
||||
}
|
||||
|
||||
const isSVG = container instanceof SVGElement
|
||||
|
||||
// HMR root reload
|
||||
if (__DEV__) {
|
||||
context.reload = () => {
|
||||
const cloned = cloneVNode(vnode)
|
||||
// compat mode will use instance if not reset to null
|
||||
cloned.component = null
|
||||
render(cloned, container, isSVG)
|
||||
}
|
||||
}
|
||||
|
||||
// resolve in-DOM template if component did not provide render
|
||||
// and no setup/mixin render functions are provided (by checking
|
||||
// that the instance is still using the placeholder render fn)
|
||||
if (hasNoRender && instance.render === emptyRender) {
|
||||
// root directives check
|
||||
if (__DEV__) {
|
||||
for (let i = 0; i < container.attributes.length; i++) {
|
||||
const attr = container.attributes[i]
|
||||
if (attr.name !== 'v-cloak' && /^(v-|:|@)/.test(attr.name)) {
|
||||
warnDeprecation(DeprecationTypes.GLOBAL_DOM_TEMPLATE_MOUNT)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
instance.render = null
|
||||
;(component as ComponentOptions).template = container.innerHTML
|
||||
finishComponentSetup(instance, __NODE_JS__, true /* skip options */)
|
||||
}
|
||||
|
||||
// clear content before mounting
|
||||
container.innerHTML = ''
|
||||
|
||||
// TODO hydration
|
||||
render(vnode, container, isSVG)
|
||||
|
||||
if (container instanceof Element) {
|
||||
container.removeAttribute('v-cloak')
|
||||
container.setAttribute('data-v-app', '')
|
||||
}
|
||||
|
||||
isMounted = true
|
||||
app._container = container
|
||||
// for devtools and telemetry
|
||||
;(container as any).__vue_app__ = app
|
||||
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
|
||||
devtoolsInitApp(app, version)
|
||||
}
|
||||
|
||||
return instance.proxy!
|
||||
}
|
||||
|
||||
instance.ctx._compat_destroy = app.unmount
|
||||
|
||||
return instance.proxy!
|
||||
}
|
||||
}
|
||||
|
||||
// dev only
|
||||
export function installLegacyConfigTraps(config: AppConfig) {
|
||||
const legacyConfigOptions: Record<string, DeprecationTypes> = {
|
||||
silent: DeprecationTypes.CONFIG_SILENT,
|
||||
devtools: DeprecationTypes.CONFIG_DEVTOOLS,
|
||||
ignoredElements: DeprecationTypes.CONFIG_IGNORED_ELEMENTS,
|
||||
keyCodes: DeprecationTypes.CONFIG_KEY_CODES,
|
||||
productionTip: DeprecationTypes.CONFIG_PRODUCTION_TIP
|
||||
}
|
||||
|
||||
Object.keys(legacyConfigOptions).forEach(key => {
|
||||
let val = (config as any)[key]
|
||||
Object.defineProperty(config, key, {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return val
|
||||
},
|
||||
set(newVal) {
|
||||
if (!isCopyingConfig) {
|
||||
warnDeprecation(legacyConfigOptions[key])
|
||||
}
|
||||
val = newVal
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
import { AppConfig } from '../apiCreateApp'
|
||||
import { DeprecationTypes, warnDeprecation } from './deprecations'
|
||||
import { isCopyingConfig } from './global'
|
||||
|
||||
// legacy config warnings
|
||||
export type LegacyConfig = {
|
||||
/**
|
||||
* @deprecated `config.silent` option has been removed
|
||||
*/
|
||||
silent?: boolean
|
||||
/**
|
||||
* @deprecated use __VUE_PROD_DEVTOOLS__ compile-time feature flag instead
|
||||
* https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags
|
||||
*/
|
||||
devtools?: boolean
|
||||
/**
|
||||
* @deprecated use `config.isCustomElement` instead
|
||||
* https://v3.vuejs.org/guide/migration/global-api.html#config-ignoredelements-is-now-config-iscustomelement
|
||||
*/
|
||||
ignoredElements?: (string | RegExp)[]
|
||||
/**
|
||||
* @deprecated
|
||||
* https://v3.vuejs.org/guide/migration/keycode-modifiers.html
|
||||
*/
|
||||
keyCodes?: Record<string, number | number[]>
|
||||
/**
|
||||
* @deprecated
|
||||
* https://v3.vuejs.org/guide/migration/global-api.html#config-productiontip-removed
|
||||
*/
|
||||
productionTip?: boolean
|
||||
}
|
||||
|
||||
export function installLegacyConfigTraps(config: AppConfig) {
|
||||
const legacyConfigOptions: Record<string, DeprecationTypes> = {
|
||||
silent: DeprecationTypes.CONFIG_SILENT,
|
||||
devtools: DeprecationTypes.CONFIG_DEVTOOLS,
|
||||
ignoredElements: DeprecationTypes.CONFIG_IGNORED_ELEMENTS,
|
||||
keyCodes: DeprecationTypes.CONFIG_KEY_CODES,
|
||||
productionTip: DeprecationTypes.CONFIG_PRODUCTION_TIP
|
||||
}
|
||||
|
||||
Object.keys(legacyConfigOptions).forEach(key => {
|
||||
let val = (config as any)[key]
|
||||
Object.defineProperty(config, key, {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return val
|
||||
},
|
||||
set(newVal) {
|
||||
if (!isCopyingConfig) {
|
||||
warnDeprecation(legacyConfigOptions[key])
|
||||
}
|
||||
val = newVal
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
import { isFunction } from '@vue/shared'
|
||||
import { App, AppContext } from '../apiCreateApp'
|
||||
import {
|
||||
ComponentOptions,
|
||||
createComponentInstance,
|
||||
finishComponentSetup,
|
||||
setupComponent
|
||||
} from '../component'
|
||||
import { devtoolsInitApp } from '../devtools'
|
||||
import { RootHydrateFunction } from '../hydration'
|
||||
import { RootRenderFunction } from '../renderer'
|
||||
import { cloneVNode, createVNode } from '../vnode'
|
||||
import { warn } from '../warning'
|
||||
import { version } from '..'
|
||||
import { DeprecationTypes, warnDeprecation } from './deprecations'
|
||||
|
||||
export function installCompatMount(
|
||||
app: App,
|
||||
context: AppContext,
|
||||
render: RootRenderFunction,
|
||||
hydrate?: RootHydrateFunction
|
||||
) {
|
||||
let isMounted = false
|
||||
|
||||
/**
|
||||
* Vue 2 supports the behavior of creating a component instance but not
|
||||
* mounting it, which is no longer possible in Vue 3 - this internal
|
||||
* function simulates that behavior.
|
||||
*/
|
||||
app._createRoot = options => {
|
||||
const component = app._component
|
||||
const vnode = createVNode(component, options.propsData || null)
|
||||
vnode.appContext = context
|
||||
|
||||
const hasNoRender =
|
||||
!isFunction(component) && !component.render && !component.template
|
||||
const emptyRender = () => {}
|
||||
|
||||
// create root instance
|
||||
const instance = createComponentInstance(vnode, null, null)
|
||||
// suppress "missing render fn" warning since it can't be determined
|
||||
// until $mount is called
|
||||
if (hasNoRender) {
|
||||
instance.render = emptyRender
|
||||
}
|
||||
setupComponent(instance, __NODE_JS__)
|
||||
vnode.component = instance
|
||||
|
||||
// $mount & $destroy
|
||||
// these are defined on ctx and picked up by the $mount/$destroy
|
||||
// public property getters on the instance proxy.
|
||||
// Note: the following assumes DOM environment since the compat build
|
||||
// only targets web. It essentially includes logic for app.mount from
|
||||
// both runtime-core AND runtime-dom.
|
||||
instance.ctx._compat_mount = (selectorOrEl: string | Element) => {
|
||||
if (isMounted) {
|
||||
__DEV__ && warn(`Root instance is already mounted.`)
|
||||
return
|
||||
}
|
||||
|
||||
let container: Element
|
||||
if (typeof selectorOrEl === 'string') {
|
||||
// eslint-disable-next-line
|
||||
const result = document.querySelector(selectorOrEl)
|
||||
if (!result) {
|
||||
__DEV__ &&
|
||||
warn(
|
||||
`Failed to mount root instance: selector "${selectorOrEl}" returned null.`
|
||||
)
|
||||
return
|
||||
}
|
||||
container = result
|
||||
} else {
|
||||
if (!selectorOrEl) {
|
||||
__DEV__ &&
|
||||
warn(
|
||||
`Failed to mount root instance: invalid mount target ${selectorOrEl}.`
|
||||
)
|
||||
return
|
||||
}
|
||||
container = selectorOrEl
|
||||
}
|
||||
|
||||
const isSVG = container instanceof SVGElement
|
||||
|
||||
// HMR root reload
|
||||
if (__DEV__) {
|
||||
context.reload = () => {
|
||||
const cloned = cloneVNode(vnode)
|
||||
// compat mode will use instance if not reset to null
|
||||
cloned.component = null
|
||||
render(cloned, container, isSVG)
|
||||
}
|
||||
}
|
||||
|
||||
// resolve in-DOM template if component did not provide render
|
||||
// and no setup/mixin render functions are provided (by checking
|
||||
// that the instance is still using the placeholder render fn)
|
||||
if (hasNoRender && instance.render === emptyRender) {
|
||||
// root directives check
|
||||
if (__DEV__) {
|
||||
for (let i = 0; i < container.attributes.length; i++) {
|
||||
const attr = container.attributes[i]
|
||||
if (attr.name !== 'v-cloak' && /^(v-|:|@)/.test(attr.name)) {
|
||||
warnDeprecation(DeprecationTypes.DOM_TEMPLATE_MOUNT)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
instance.render = null
|
||||
;(component as ComponentOptions).template = container.innerHTML
|
||||
finishComponentSetup(instance, __NODE_JS__, true /* skip options */)
|
||||
}
|
||||
|
||||
// clear content before mounting
|
||||
container.innerHTML = ''
|
||||
|
||||
// TODO hydration
|
||||
render(vnode, container, isSVG)
|
||||
|
||||
if (container instanceof Element) {
|
||||
container.removeAttribute('v-cloak')
|
||||
container.setAttribute('data-v-app', '')
|
||||
}
|
||||
|
||||
isMounted = true
|
||||
app._container = container
|
||||
// for devtools and telemetry
|
||||
;(container as any).__vue_app__ = app
|
||||
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
|
||||
devtoolsInitApp(app, version)
|
||||
}
|
||||
|
||||
return instance.proxy!
|
||||
}
|
||||
|
||||
instance.ctx._compat_destroy = app.unmount
|
||||
|
||||
return instance.proxy!
|
||||
}
|
||||
}
|
34
packages/runtime-core/src/compat/instance.ts
Normal file
34
packages/runtime-core/src/compat/instance.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { extend, NOOP } from '@vue/shared'
|
||||
import { PublicPropertiesMap } from '../componentPublicInstance'
|
||||
import { DeprecationTypes, warnDeprecation } from './deprecations'
|
||||
|
||||
export function installCompatInstanceProperties(map: PublicPropertiesMap) {
|
||||
const set = (target: any, key: any, val: any) => {
|
||||
target[key] = val
|
||||
}
|
||||
|
||||
const del = (target: any, key: any) => {
|
||||
delete target[key]
|
||||
}
|
||||
|
||||
extend(map, {
|
||||
$set: () => {
|
||||
__DEV__ && warnDeprecation(DeprecationTypes.INSTANCE_SET)
|
||||
return set
|
||||
},
|
||||
$delete: () => {
|
||||
__DEV__ && warnDeprecation(DeprecationTypes.INSTANCE_DELETE)
|
||||
return del
|
||||
},
|
||||
$mount: i => {
|
||||
__DEV__ && warnDeprecation(DeprecationTypes.INSTANCE_MOUNT)
|
||||
// root mount override from ./global.ts in installCompatMount
|
||||
return i.ctx._compat_mount || NOOP
|
||||
},
|
||||
$destroy: i => {
|
||||
__DEV__ && warnDeprecation(DeprecationTypes.INSTANCE_DESTROY)
|
||||
// root destroy override from ./global.ts in installCompatMount
|
||||
return i.ctx._compat_destroy || NOOP
|
||||
}
|
||||
} as PublicPropertiesMap)
|
||||
}
|
@ -41,7 +41,8 @@ import { markAttrsAccessed } from './componentRenderUtils'
|
||||
import { currentRenderingInstance } from './componentRenderContext'
|
||||
import { warn } from './warning'
|
||||
import { UnionToIntersection } from './helpers/typeUtils'
|
||||
import { warnDeprecation, DeprecationTypes } from './compat/deprecations'
|
||||
import { installCompatInstanceProperties } from './compat/instance'
|
||||
|
||||
/**
|
||||
* Custom properties added to component instances in any way and can be accessed through `this`
|
||||
*
|
||||
@ -202,7 +203,10 @@ export type ComponentPublicInstance<
|
||||
M &
|
||||
ComponentCustomProperties
|
||||
|
||||
type PublicPropertiesMap = Record<string, (i: ComponentInternalInstance) => any>
|
||||
export type PublicPropertiesMap = Record<
|
||||
string,
|
||||
(i: ComponentInternalInstance) => any
|
||||
>
|
||||
|
||||
/**
|
||||
* #2437 In Vue 3, functional components do not have a public instance proxy but
|
||||
@ -235,22 +239,7 @@ const publicPropertiesMap: PublicPropertiesMap = extend(Object.create(null), {
|
||||
} as PublicPropertiesMap)
|
||||
|
||||
if (__COMPAT__) {
|
||||
extend(publicPropertiesMap, {
|
||||
$mount: i => {
|
||||
if (__DEV__) {
|
||||
warnDeprecation(DeprecationTypes.$MOUNT)
|
||||
}
|
||||
// root mount override from apiCreateApp.ts
|
||||
return i.ctx._compat_mount || NOOP
|
||||
},
|
||||
$destroy: i => {
|
||||
if (__DEV__) {
|
||||
warnDeprecation(DeprecationTypes.$DESTROY)
|
||||
}
|
||||
// root destroy override from apiCreateApp.ts
|
||||
return i.ctx._compat_destroy || NOOP
|
||||
}
|
||||
} as PublicPropertiesMap)
|
||||
installCompatInstanceProperties(publicPropertiesMap)
|
||||
}
|
||||
|
||||
const enum AccessTypes {
|
||||
|
@ -78,7 +78,7 @@ export const createApp = ((...args) => {
|
||||
for (let i = 0; i < container.attributes.length; i++) {
|
||||
const attr = container.attributes[i]
|
||||
if (attr.name !== 'v-cloak' && /^(v-|:|@)/.test(attr.name)) {
|
||||
warnDeprecation(DeprecationTypes.DOM_TEMPLATE_MOUNT)
|
||||
warnDeprecation(DeprecationTypes.GLOBAL_DOM_TEMPLATE_MOUNT)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
registerRuntimeCompiler,
|
||||
RenderFunction,
|
||||
warn,
|
||||
createApp,
|
||||
createCompatVue
|
||||
} from '@vue/runtime-dom'
|
||||
import { isString, NOOP, generateCodeFrame, extend } from '@vue/shared'
|
||||
@ -91,7 +92,7 @@ function compileToFunction(
|
||||
|
||||
registerRuntimeCompiler(compileToFunction)
|
||||
|
||||
const Vue = createCompatVue()
|
||||
const Vue = createCompatVue(createApp)
|
||||
|
||||
Vue.compile = compileToFunction
|
||||
extend(Vue, runtimeDom)
|
||||
|
Loading…
x
Reference in New Issue
Block a user