diff --git a/packages/runtime-core/src/apiWatch.ts b/packages/runtime-core/src/apiWatch.ts index b2cf4500..fa476f15 100644 --- a/packages/runtime-core/src/apiWatch.ts +++ b/packages/runtime-core/src/apiWatch.ts @@ -36,6 +36,7 @@ import { queuePostRenderEffect } from './renderer' import { warn } from './warning' import { DeprecationTypes } from './compat/compatConfig' import { checkCompatEnabled, isCompatEnabled } from './compat/compatConfig' +import { ObjectWatchOptionItem } from './componentOptions' export type WatchEffect = (onInvalidate: InvalidateCbRegistrator) => void @@ -354,7 +355,7 @@ function doWatch( export function instanceWatch( this: ComponentInternalInstance, source: string | Function, - cb: WatchCallback, + value: WatchCallback | ObjectWatchOptionItem, options?: WatchOptions ): WatchStopHandle { const publicThis = this.proxy as any @@ -363,6 +364,13 @@ export function instanceWatch( ? createPathGetter(publicThis, source) : () => publicThis[source] : source.bind(publicThis) + let cb + if (isFunction(value)) { + cb = value + } else { + cb = value.handler as Function + options = value + } return doWatch(getter, cb.bind(publicThis), options, this) } diff --git a/packages/runtime-core/src/compat/global.ts b/packages/runtime-core/src/compat/global.ts index de89c0a9..17b71dab 100644 --- a/packages/runtime-core/src/compat/global.ts +++ b/packages/runtime-core/src/compat/global.ts @@ -109,6 +109,8 @@ 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) @@ -145,7 +147,10 @@ export function createCompatVue( // copy prototype augmentations as config.globalProperties if (isCompatEnabled(DeprecationTypes.GLOBAL_PROTOTYPE, null)) { - app.config.globalProperties = Ctor.prototype + app.config.globalProperties = extend( + Object.create(Ctor.prototype), + singletonApp.config.globalProperties + ) } let hasPrototypeAugmentations = false for (const key in Ctor.prototype) { diff --git a/packages/runtime-core/src/compat/instance.ts b/packages/runtime-core/src/compat/instance.ts index 96525a68..1f4dec7c 100644 --- a/packages/runtime-core/src/compat/instance.ts +++ b/packages/runtime-core/src/compat/instance.ts @@ -1,4 +1,11 @@ -import { extend, NOOP, toDisplayString, toNumber } from '@vue/shared' +import { + extend, + looseEqual, + looseIndexOf, + NOOP, + toDisplayString, + toNumber +} from '@vue/shared' import { PublicPropertiesMap } from '../componentPublicInstance' import { getCompatChildren } from './instanceChildren' import { @@ -14,13 +21,17 @@ import { compatH } from './renderFn' import { createCommentVNode, createTextVNode } from '../vnode' import { renderList } from '../helpers/renderList' import { + legacyBindDynamicKeys, legacyBindObjectListeners, legacyBindObjectProps, legacyCheckKeyCodes, + legacyMarkOnce, + legacyPrependModifier, legacyRenderSlot, legacyRenderStatic, legacyresolveScopedSlots } from './renderHelpers' +import { resolveFilter } from '../helpers/resolveAssets' export function installCompatInstanceProperties(map: PublicPropertiesMap) { const set = (target: any, key: any, val: any) => { @@ -85,16 +96,22 @@ export function installCompatInstanceProperties(map: PublicPropertiesMap) { $createElement: () => compatH, _self: i => i.proxy, _c: () => compatH, + _o: () => legacyMarkOnce, _n: () => toNumber, _s: () => toDisplayString, _l: () => renderList, _t: i => legacyRenderSlot.bind(null, i), - _b: () => legacyBindObjectProps, - _e: () => createCommentVNode, - _v: () => createTextVNode, + _q: () => looseEqual, + _i: () => looseIndexOf, _m: i => legacyRenderStatic.bind(null, i), - _g: () => legacyBindObjectListeners, + _f: () => resolveFilter, + _k: i => legacyCheckKeyCodes.bind(null, i), + _b: () => legacyBindObjectProps, + _v: () => createTextVNode, + _e: () => createCommentVNode, _u: () => legacyresolveScopedSlots, - _k: i => legacyCheckKeyCodes.bind(null, i) + _g: () => legacyBindObjectListeners, + _d: () => legacyBindDynamicKeys, + _p: () => legacyPrependModifier } as PublicPropertiesMap) } diff --git a/packages/runtime-core/src/compat/renderHelpers.ts b/packages/runtime-core/src/compat/renderHelpers.ts index 0b90632d..2eaaa459 100644 --- a/packages/runtime-core/src/compat/renderHelpers.ts +++ b/packages/runtime-core/src/compat/renderHelpers.ts @@ -162,3 +162,21 @@ function isKeyNotMatch(expect: T | T[], actual: T): boolean { return expect !== actual } } + +export function legacyMarkOnce(tree: VNode) { + return tree +} + +export function legacyBindDynamicKeys(props: any, values: any[]) { + for (let i = 0; i < values.length; i += 2) { + const key = values[i] + if (typeof key === 'string' && key) { + props[values[i]] = values[i + 1] + } + } + return props +} + +export function legacyPrependModifier(value: any, symbol: string) { + return typeof value === 'string' ? symbol + value : value +} diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index 2e729bfe..40755e80 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -360,10 +360,11 @@ export type ExtractComputedReturns = { : T[key] extends (...args: any[]) => infer TReturn ? TReturn : never } -type WatchOptionItem = - | string - | WatchCallback - | { handler: WatchCallback | string } & WatchOptions +export type ObjectWatchOptionItem = { + handler: WatchCallback | string +} & WatchOptions + +type WatchOptionItem = string | WatchCallback | ObjectWatchOptionItem type ComponentWatchOptionItem = WatchOptionItem | WatchOptionItem[] @@ -949,7 +950,7 @@ function resolveData( } } -function createWatcher( +export function createWatcher( raw: ComponentWatchOptionItem, ctx: Data, publicThis: ComponentPublicInstance,