wip: watch array compat

This commit is contained in:
Evan You 2021-04-07 12:24:45 -04:00
parent 69fafb437a
commit 208bef5d97
4 changed files with 56 additions and 14 deletions

View File

@ -33,6 +33,8 @@ import {
} from './errorHandling' } from './errorHandling'
import { queuePostRenderEffect } from './renderer' import { queuePostRenderEffect } from './renderer'
import { warn } from './warning' import { warn } from './warning'
import { DeprecationTypes, warnDeprecation } from './compat/deprecations'
import { isCompatEnabled } from './compat/compatConfig'
export type WatchEffect = (onInvalidate: InvalidateCbRegistrator) => void export type WatchEffect = (onInvalidate: InvalidateCbRegistrator) => void
@ -217,6 +219,21 @@ function doWatch(
__DEV__ && warnInvalidSource(source) __DEV__ && warnInvalidSource(source)
} }
// 2.x array mutation watch compat
if (__COMPAT__ && cb && !deep) {
const baseGetter = getter
getter = () => {
const val = baseGetter()
if (isArray(val)) {
__DEV__ && warnDeprecation(DeprecationTypes.WATCH_ARRAY)
if (isCompatEnabled(DeprecationTypes.WATCH_ARRAY)) {
traverse(val)
}
}
return val
}
}
if (cb && deep) { if (cb && deep) {
const baseGetter = getter const baseGetter = getter
getter = () => traverse(baseGetter()) getter = () => traverse(baseGetter())
@ -254,7 +271,14 @@ function doWatch(
if (cb) { if (cb) {
// watch(source, cb) // watch(source, cb)
const newValue = runner() const newValue = runner()
if (deep || forceTrigger || hasChanged(newValue, oldValue)) { if (
deep ||
forceTrigger ||
hasChanged(newValue, oldValue) ||
(__COMPAT__ &&
isArray(newValue) &&
isCompatEnabled(DeprecationTypes.WATCH_ARRAY))
) {
// cleanup before running cb again // cleanup before running cb again
if (cleanup) { if (cleanup) {
cleanup() cleanup()

View File

@ -16,11 +16,16 @@ export function configureCompat(config: CompatConfig) {
extend(globalCompatConfig, config) extend(globalCompatConfig, config)
} }
/**
* @internal
*/
export function getCompatConfig( export function getCompatConfig(
key: DeprecationTypes key: DeprecationTypes
): DeprecationConfigItem | undefined { ): DeprecationConfigItem | undefined {
return globalCompatConfig[key] return globalCompatConfig[key]
} }
/**
* @internal
*/
export function isCompatEnabled(key: DeprecationTypes): boolean {
const config = getCompatConfig(key)
return !config || config.mode !== 3
}

View File

@ -28,11 +28,10 @@ export const enum DeprecationTypes {
OPTIONS_BEFORE_DESTROY = 'OPTIONS_BEFORE_DESTROY', OPTIONS_BEFORE_DESTROY = 'OPTIONS_BEFORE_DESTROY',
OPTIONS_DESTROYED = 'OPTIONS_DESTROYED', OPTIONS_DESTROYED = 'OPTIONS_DESTROYED',
V_ON_KEYCODE_MODIFIER = 'V_ON_KEYCODE_MODIFIER',
PROPS_DEFAULT_THIS = 'PROPS_DEFAULT_THIS', PROPS_DEFAULT_THIS = 'PROPS_DEFAULT_THIS',
CUSTOM_DIR = 'CUSTOM_DIR', CUSTOM_DIR = 'CUSTOM_DIR',
WATCH_ARRAY = 'WATCH_ARRAY'
V_ON_KEYCODE_MODIFIER = 'V_ON_KEYCODE_MODIFIER'
} }
type DeprecationData = { type DeprecationData = {
@ -181,6 +180,13 @@ const deprecationMessages: Record<DeprecationTypes, DeprecationData> = {
message: `\`destroyed\` has been renamed to \`unmounted\`.` message: `\`destroyed\` has been renamed to \`unmounted\`.`
}, },
[DeprecationTypes.V_ON_KEYCODE_MODIFIER]: {
message:
`Using keyCode as v-on modifier is no longer supported. ` +
`Use kebab-case key name modifiers instead.`,
link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html`
},
[DeprecationTypes.PROPS_DEFAULT_THIS]: { [DeprecationTypes.PROPS_DEFAULT_THIS]: {
message: (key: string) => message: (key: string) =>
`props default value function no longer has access to "this". ` + `props default value function no longer has access to "this". ` +
@ -195,11 +201,15 @@ const deprecationMessages: Record<DeprecationTypes, DeprecationData> = {
link: `https://v3.vuejs.org/guide/migration/custom-directives.html` link: `https://v3.vuejs.org/guide/migration/custom-directives.html`
}, },
[DeprecationTypes.V_ON_KEYCODE_MODIFIER]: { [DeprecationTypes.WATCH_ARRAY]: {
message: message:
`Using keyCode as v-on modifier is no longer supported. ` + `"watch" option or vm.$watch on an array value will no longer ` +
`Use kebab-case key name modifiers instead.`, `trigger on array mutation unless the "deep" option is specified. ` +
link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html` `If current usage is intended, you can suppress this warning with:` +
`\n\n configureCompat({ ${
DeprecationTypes.WATCH_ARRAY
}: { mode: 3 }})\n`,
link: `https://v3.vuejs.org/guide/migration/watch.html`
} }
} }
@ -215,7 +225,10 @@ export function warnDeprecation(key: DeprecationTypes, ...args: any[]) {
// check user config // check user config
const config = getCompatConfig(key) const config = getCompatConfig(key)
if (config && config.warning === false) { if (
config &&
(config.warning === false || (config.mode === 3 && config.warning !== true))
) {
return return
} }

View File

@ -288,12 +288,12 @@ export { LegacyConfig } from './compat/globalConfig'
import { warnDeprecation } from './compat/deprecations' import { warnDeprecation } from './compat/deprecations'
import { createCompatVue } from './compat/global' import { createCompatVue } from './compat/global'
import { getCompatConfig } from './compat/compatConfig' import { isCompatEnabled } from './compat/compatConfig'
const _compatUtils = { const _compatUtils = {
warnDeprecation, warnDeprecation,
createCompatVue, createCompatVue,
getCompatConfig isCompatEnabled
} }
export const compatUtils = (__COMPAT__ export const compatUtils = (__COMPAT__