wip: more compat tweaks
This commit is contained in:
parent
98bc9a26e9
commit
7e0224aa8c
@ -6,7 +6,7 @@ import {
|
||||
createApp,
|
||||
shallowReadonly
|
||||
} from '@vue/runtime-test'
|
||||
import { ComponentInternalInstance } from '../src/component'
|
||||
import { ComponentInternalInstance, ComponentOptions } from '../src/component'
|
||||
|
||||
describe('component: proxy', () => {
|
||||
test('data', () => {
|
||||
@ -93,7 +93,9 @@ describe('component: proxy', () => {
|
||||
expect(instanceProxy.$root).toBe(instance!.root.proxy)
|
||||
expect(instanceProxy.$emit).toBe(instance!.emit)
|
||||
expect(instanceProxy.$el).toBe(instance!.vnode.el)
|
||||
expect(instanceProxy.$options).toBe(instance!.type)
|
||||
expect(instanceProxy.$options).toBe(
|
||||
(instance!.type as ComponentOptions).__merged
|
||||
)
|
||||
expect(() => (instanceProxy.$data = {})).toThrow(TypeError)
|
||||
expect(`Attempting to mutate public property "$data"`).toHaveBeenWarned()
|
||||
|
||||
|
@ -26,13 +26,18 @@ export function convertLegacyComponent(
|
||||
return comp
|
||||
}
|
||||
|
||||
// 2.x constructor
|
||||
if (isFunction(comp) && comp.cid) {
|
||||
comp = comp.options
|
||||
}
|
||||
|
||||
// 2.x async component
|
||||
// since after disabling this, plain functions are still valid usage, do not
|
||||
// use softAssert here.
|
||||
if (
|
||||
isFunction(comp) &&
|
||||
checkCompatEnabled(DeprecationTypes.COMPONENT_ASYNC, instance, comp)
|
||||
) {
|
||||
// since after disabling this, plain functions are still valid usage, do not
|
||||
// use softAssert here.
|
||||
return convertLegacyAsyncComponent(comp)
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,14 @@ export type CompatVue = Pick<App, 'version' | 'component' | 'directive'> & {
|
||||
* @deprecated filters have been removed from Vue 3.
|
||||
*/
|
||||
filter(name: string, arg: any): null
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
cid: number
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
options: ComponentOptions
|
||||
|
||||
configureCompat: typeof configureCompat
|
||||
}
|
||||
@ -109,8 +117,6 @@ export function createCompatVue(
|
||||
} as any
|
||||
|
||||
const singletonApp = createApp({})
|
||||
// @ts-ignore
|
||||
singletonApp.prototype = singletonApp.config.globalProperties
|
||||
|
||||
function createCompatApp(options: ComponentOptions = {}, Ctor: any) {
|
||||
assertCompatEnabled(DeprecationTypes.GLOBAL_MOUNT, null)
|
||||
@ -174,18 +180,26 @@ export function createCompatVue(
|
||||
Vue.version = __VERSION__
|
||||
Vue.config = singletonApp.config
|
||||
Vue.nextTick = nextTick
|
||||
Vue.options = { _base: Vue }
|
||||
|
||||
Vue.extend = ((options: ComponentOptions = {}) => {
|
||||
let cid = 1
|
||||
Vue.cid = cid
|
||||
|
||||
function extendCtor(this: any, extendOptions: ComponentOptions = {}) {
|
||||
assertCompatEnabled(DeprecationTypes.GLOBAL_EXTEND, null)
|
||||
if (isFunction(extendOptions)) {
|
||||
extendOptions = extendOptions.options
|
||||
}
|
||||
|
||||
const Super = this
|
||||
function SubVue(inlineOptions?: ComponentOptions) {
|
||||
if (!inlineOptions) {
|
||||
return createCompatApp(options, SubVue)
|
||||
return createCompatApp(extendOptions, SubVue)
|
||||
} else {
|
||||
return createCompatApp(
|
||||
{
|
||||
el: inlineOptions.el,
|
||||
extends: options,
|
||||
extends: extendOptions,
|
||||
mixins: [inlineOptions]
|
||||
},
|
||||
SubVue
|
||||
@ -194,8 +208,20 @@ export function createCompatVue(
|
||||
}
|
||||
SubVue.prototype = Object.create(Vue.prototype)
|
||||
SubVue.prototype.constructor = SubVue
|
||||
SubVue.options = mergeOptions(
|
||||
extend({}, Super.options) as ComponentOptions,
|
||||
extendOptions
|
||||
)
|
||||
|
||||
SubVue.options._base = SubVue
|
||||
SubVue.extend = extendCtor.bind(SubVue)
|
||||
SubVue.mixin = Super.mixin
|
||||
SubVue.use = Super.use
|
||||
SubVue.cid = ++cid
|
||||
return SubVue
|
||||
}) as any
|
||||
}
|
||||
|
||||
Vue.extend = extendCtor.bind(Vue) as any
|
||||
|
||||
Vue.set = (target, key, value) => {
|
||||
assertCompatEnabled(DeprecationTypes.GLOBAL_SET, null)
|
||||
@ -213,7 +239,11 @@ export function createCompatVue(
|
||||
}
|
||||
|
||||
Vue.use = (p, ...options) => {
|
||||
singletonApp.use(p, ...options)
|
||||
if (p && isFunction(p.install)) {
|
||||
p.install(Vue as any, ...options)
|
||||
} else if (isFunction(p)) {
|
||||
p(Vue as any, ...options)
|
||||
}
|
||||
return Vue
|
||||
}
|
||||
|
||||
|
@ -110,8 +110,11 @@ export function installLegacyConfigProperties(config: AppConfig) {
|
||||
strats.watch = mergeObjectOptions
|
||||
}
|
||||
|
||||
function mergeHook(to: Function[] | undefined, from: Function | Function[]) {
|
||||
return Array.from(new Set([...(to || []), from]))
|
||||
function mergeHook(
|
||||
to: Function[] | Function | undefined,
|
||||
from: Function | Function[]
|
||||
) {
|
||||
return Array.from(new Set([...(isArray(to) ? to : to ? [to] : []), from]))
|
||||
}
|
||||
|
||||
function mergeObjectOptions(to: Object | undefined, from: Object | undefined) {
|
||||
|
@ -32,6 +32,7 @@ import {
|
||||
legacyresolveScopedSlots
|
||||
} from './renderHelpers'
|
||||
import { resolveFilter } from '../helpers/resolveAssets'
|
||||
import { resolveMergedOptions } from '../componentOptions'
|
||||
|
||||
export function installCompatInstanceProperties(map: PublicPropertiesMap) {
|
||||
const set = (target: any, key: any, val: any) => {
|
||||
@ -92,9 +93,18 @@ export function installCompatInstanceProperties(map: PublicPropertiesMap) {
|
||||
$children: getCompatChildren,
|
||||
$listeners: getCompatListeners,
|
||||
|
||||
// inject parent into $options for compat
|
||||
$options: i => {
|
||||
let res = resolveMergedOptions(i)
|
||||
if (res === i.type) res = i.type.__merged = extend({}, res)
|
||||
res.parent = i.proxy!.$parent
|
||||
return res
|
||||
},
|
||||
|
||||
// v2 render helpers
|
||||
$createElement: () => compatH,
|
||||
_self: i => i.proxy,
|
||||
_uid: i => i.uid,
|
||||
_c: () => compatH,
|
||||
_o: () => legacyMarkOnce,
|
||||
_n: () => toNumber,
|
||||
|
@ -3,6 +3,7 @@ import {
|
||||
hyphenate,
|
||||
isArray,
|
||||
isObject,
|
||||
isString,
|
||||
makeMap,
|
||||
normalizeClass,
|
||||
normalizeStyle,
|
||||
@ -304,12 +305,17 @@ export function defineLegacyVNodeProperties(vnode: VNode) {
|
||||
if (
|
||||
isCompatEnabled(DeprecationTypes.RENDER_FUNCTION, currentRenderingInstance)
|
||||
) {
|
||||
const context = currentRenderingInstance
|
||||
const getInstance = () => vnode.component && vnode.component.proxy
|
||||
let componentOptions: any
|
||||
Object.defineProperties(vnode, {
|
||||
tag: { get: () => vnode.type },
|
||||
data: { get: () => vnode.props, set: p => (vnode.props = p) },
|
||||
elm: { get: () => vnode.el },
|
||||
componentInstance: { get: getInstance },
|
||||
child: { get: getInstance },
|
||||
text: { get: () => (isString(vnode.children) ? vnode.children : null) },
|
||||
context: { get: () => context && context.proxy },
|
||||
componentOptions: {
|
||||
get: () => {
|
||||
if (vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT) {
|
||||
|
@ -509,6 +509,10 @@ export function applyOptions(
|
||||
deferredProvide: (Data | Function)[] = [],
|
||||
asMixin: boolean = false
|
||||
) {
|
||||
if (__COMPAT__ && isFunction(options)) {
|
||||
options = options.options
|
||||
}
|
||||
|
||||
const {
|
||||
// composition
|
||||
mixins,
|
||||
@ -1005,6 +1009,10 @@ export function mergeOptions(
|
||||
from: any,
|
||||
instance?: ComponentInternalInstance
|
||||
) {
|
||||
if (__COMPAT__ && isFunction(from)) {
|
||||
from = from.options
|
||||
}
|
||||
|
||||
const strats = instance && instance.appContext.config.optionMergeStrategies
|
||||
const { mixins, extends: extendsOptions } = from
|
||||
|
||||
@ -1019,4 +1027,5 @@ export function mergeOptions(
|
||||
to[key] = from[key]
|
||||
}
|
||||
}
|
||||
return to
|
||||
}
|
||||
|
@ -429,6 +429,9 @@ export function normalizePropsOptions(
|
||||
let hasExtends = false
|
||||
if (__FEATURE_OPTIONS_API__ && !isFunction(comp)) {
|
||||
const extendProps = (raw: ComponentOptions) => {
|
||||
if (__COMPAT__ && isFunction(raw)) {
|
||||
raw = raw.options
|
||||
}
|
||||
hasExtends = true
|
||||
const [props, keys] = normalizePropsOptions(raw, appContext, true)
|
||||
extend(normalized, props)
|
||||
|
@ -107,7 +107,11 @@ const normalizeVNodeSlots = (
|
||||
instance: ComponentInternalInstance,
|
||||
children: VNodeNormalizedChildren
|
||||
) => {
|
||||
if (__DEV__ && !isKeepAlive(instance.vnode)) {
|
||||
if (
|
||||
__DEV__ &&
|
||||
!isKeepAlive(instance.vnode) &&
|
||||
!(__COMPAT__ && isCompatEnabled(DeprecationTypes.RENDER_FUNCTION, instance))
|
||||
) {
|
||||
warn(
|
||||
`Non-function value encountered for default slot. ` +
|
||||
`Prefer function slots for better performance.`
|
||||
|
Loading…
Reference in New Issue
Block a user