]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: refactor deprecations into a single file
authorEvan You <yyx990803@gmail.com>
Mon, 12 Apr 2021 22:47:50 +0000 (18:47 -0400)
committerEvan You <yyx990803@gmail.com>
Mon, 12 Apr 2021 22:47:50 +0000 (18:47 -0400)
19 files changed:
packages/runtime-core/src/apiWatch.ts
packages/runtime-core/src/compat/compatConfig.ts
packages/runtime-core/src/compat/component.ts
packages/runtime-core/src/compat/customDirective.ts
packages/runtime-core/src/compat/data.ts
packages/runtime-core/src/compat/deprecations.ts [deleted file]
packages/runtime-core/src/compat/global.ts
packages/runtime-core/src/compat/globalConfig.ts
packages/runtime-core/src/compat/instance.ts
packages/runtime-core/src/compat/instanceChildren.ts
packages/runtime-core/src/compat/instanceEventEmitter.ts
packages/runtime-core/src/compat/instanceListeners.ts
packages/runtime-core/src/compat/props.ts
packages/runtime-core/src/compat/renderFn.ts
packages/runtime-core/src/compat/vModel.ts
packages/runtime-core/src/componentOptions.ts
packages/runtime-core/src/componentProps.ts
packages/runtime-core/src/index.ts
packages/runtime-core/src/renderer.ts

index e98d54788577c2dead222015bc20b00d6fcb3336..5dc7929ee3b2d28335593073242afa6a43c3aeb9 100644 (file)
@@ -33,7 +33,7 @@ import {
 } from './errorHandling'
 import { queuePostRenderEffect } from './renderer'
 import { warn } from './warning'
-import { DeprecationTypes } from './compat/deprecations'
+import { DeprecationTypes } from './compat/compatConfig'
 import { checkCompatEnabled, isCompatEnabled } from './compat/compatConfig'
 
 export type WatchEffect = (onInvalidate: InvalidateCbRegistrator) => void
index ee2bfcacb4bb3d6967e8d0a1987f58660090214c..5f53785923611235f532f3a202999ceba8f49f3e 100644 (file)
@@ -1,6 +1,454 @@
-import { extend } from '@vue/shared'
-import { ComponentInternalInstance, ComponentOptions } from '../component'
-import { DeprecationTypes, warnDeprecation } from './deprecations'
+import { extend, hasOwn, isArray } from '@vue/shared'
+import {
+  ComponentInternalInstance,
+  ComponentOptions,
+  formatComponentName,
+  getComponentName,
+  getCurrentInstance,
+  isRuntimeOnly
+} from '../component'
+import { warn } from '../warning'
+
+export const enum DeprecationTypes {
+  GLOBAL_MOUNT = 'GLOBAL_MOUNT',
+  GLOBAL_MOUNT_CONTAINER = 'GLOBAL_MOUNT_CONTAINER',
+  GLOBAL_EXTEND = 'GLOBAL_EXTEND',
+  GLOBAL_PROTOTYPE = 'GLOBAL_PROTOTYPE',
+  GLOBAL_SET = 'GLOBAL_SET',
+  GLOBAL_DELETE = 'GLOBAL_DELETE',
+  GLOBAL_OBSERVABLE = 'GLOBAL_OBSERVABLE',
+  GLOBAL_UTIL = 'GLOBAL_UTIL',
+
+  CONFIG_SILENT = 'CONFIG_SILENT',
+  CONFIG_DEVTOOLS = 'CONFIG_DEVTOOLS',
+  CONFIG_KEY_CODES = 'CONFIG_KEY_CODES',
+  CONFIG_PRODUCTION_TIP = 'CONFIG_PRODUCTION_TIP',
+  CONFIG_IGNORED_ELEMENTS = 'CONFIG_IGNORED_ELEMENTS',
+
+  INSTANCE_SET = 'INSTANCE_SET',
+  INSTANCE_DELETE = 'INSTANCE_DELETE',
+  INSTANCE_DESTROY = 'INSTANCE_DESTROY',
+  INSTANCE_EVENT_EMITTER = 'INSTANCE_EVENT_EMITTER',
+  INSTANCE_EVENT_HOOKS = 'INSTANCE_EVENT_HOOKS',
+  INSTANCE_CHILDREN = 'INSTANCE_CHILDREN',
+  INSTANCE_LISTENERS = 'INSTANCE_LISTENERS',
+  INSTANCE_SCOPED_SLOTS = 'INSTANCE_SCOPED_SLOTS',
+  INSTANCE_ATTRS_CLASS_STYLE = 'INSTANCE_ATTRS_CLASS_STYLE',
+
+  OPTIONS_DATA_FN = 'OPTIONS_DATA_FN',
+  OPTIONS_DATA_MERGE = 'OPTIONS_DATA_MERGE',
+  OPTIONS_BEFORE_DESTROY = 'OPTIONS_BEFORE_DESTROY',
+  OPTIONS_DESTROYED = 'OPTIONS_DESTROYED',
+
+  WATCH_ARRAY = 'WATCH_ARRAY',
+  PROPS_DEFAULT_THIS = 'PROPS_DEFAULT_THIS',
+
+  V_ON_KEYCODE_MODIFIER = 'V_ON_KEYCODE_MODIFIER',
+  CUSTOM_DIR = 'CUSTOM_DIR',
+
+  ATTR_FALSE_VALUE = 'ATTR_FALSE_VALUE',
+  ATTR_ENUMERATED_COERSION = 'ATTR_ENUMERATED_COERSION',
+
+  TRANSITION_CLASSES = 'TRANSITION_CLASSES',
+  TRANSITION_GROUP_ROOT = 'TRANSITION_GROUP_ROOT',
+
+  COMPONENT_ASYNC = 'COMPONENT_ASYNC',
+  COMPONENT_FUNCTIONAL = 'COMPONENT_FUNCTIONAL',
+  COMPONENT_V_MODEL = 'COMPONENT_V_MODEL',
+
+  RENDER_FUNCTION = 'RENDER_FUNCTION'
+}
+
+type DeprecationData = {
+  message: string | ((...args: any[]) => string)
+  link?: string
+}
+
+const deprecationData: Record<DeprecationTypes, DeprecationData> = {
+  [DeprecationTypes.GLOBAL_MOUNT]: {
+    message:
+      `The global app bootstrapping 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.GLOBAL_MOUNT_CONTAINER]: {
+    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.GLOBAL_EXTEND]: {
+    message:
+      `Vue.extend() has been removed in Vue 3. ` +
+      `Use defineComponent() instead.`,
+    link: `https://v3.vuejs.org/api/global-api.html#definecomponent`
+  },
+
+  [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_UTIL]: {
+    message:
+      `Vue.util has been removed. Please refactor to avoid its usage ` +
+      `since it was an internal API even in Vue 2.`
+  },
+
+  [DeprecationTypes.CONFIG_SILENT]: {
+    message:
+      `config.silent has been removed because it is not good practice to ` +
+      `intentionally suppress warnings. You can use your browser console's ` +
+      `filter features to focus on relevant messages.`
+  },
+
+  [DeprecationTypes.CONFIG_DEVTOOLS]: {
+    message:
+      `config.devtools has been removed. To enable devtools for ` +
+      `production, configure the __VUE_PROD_DEVTOOLS__ compile-time flag.`,
+    link: `https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags`
+  },
+
+  [DeprecationTypes.CONFIG_KEY_CODES]: {
+    message:
+      `config.keyCodes has been removed. ` +
+      `In Vue 3, you can directly use the kebab-case key names as v-on modifiers.`,
+    link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html`
+  },
+
+  [DeprecationTypes.CONFIG_PRODUCTION_TIP]: {
+    message: `config.productionTip has been removed.`,
+    link: `https://v3.vuejs.org/guide/migration/global-api.html#config-productiontip-removed`
+  },
+
+  [DeprecationTypes.CONFIG_IGNORED_ELEMENTS]: {
+    message: () => {
+      let msg = `config.ignoredElements has been removed.`
+      if (isRuntimeOnly()) {
+        msg += ` Pass the "isCustomElement" option to @vue/compiler-dom instead.`
+      } else {
+        msg += ` Use config.isCustomElement instead.`
+      }
+      return msg
+    },
+    link: `https://v3.vuejs.org/guide/migration/global-api.html#config-ignoredelements-is-now-config-iscustomelement`
+  },
+
+  [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_DESTROY]: {
+    message: `vm.$destroy() has been removed. Use app.unmount() instead.`,
+    link: `https://v3.vuejs.org/api/application-api.html#unmount`
+  },
+
+  [DeprecationTypes.INSTANCE_EVENT_EMITTER]: {
+    message:
+      `vm.$on/$once/$off() have been removed. ` +
+      `Use an external event emitter library instead.`,
+    link: `https://v3.vuejs.org/guide/migration/events-api.html`
+  },
+
+  [DeprecationTypes.INSTANCE_EVENT_HOOKS]: {
+    message: event =>
+      `"${event}" lifecycle events are no longer supported. From templates, ` +
+      `use the "vnode" prefix instead of "hook:". For example, @${event} ` +
+      `should be changed to @vnode-${event.slice(5)}. ` +
+      `From JavaScript, use Composition API to dynamically register lifecycle ` +
+      `hooks.`,
+    link: `https://v3.vuejs.org/guide/migration/vnode-lifecycle-events.html`
+  },
+
+  [DeprecationTypes.INSTANCE_CHILDREN]: {
+    message:
+      `vm.$children has been removed. Consider refactoring your logic ` +
+      `to avoid relying on direct access to child components.`,
+    link: `https://v3.vuejs.org/guide/migration/children.html`
+  },
+
+  [DeprecationTypes.INSTANCE_LISTENERS]: {
+    message:
+      `vm.$listeners has been removed. Parent v-on listeners are now ` +
+      `included in vm.$attrs and it is no longer necessary to separately use ` +
+      `v-on="$listeners" if you are already using v-bind="$attrs".`,
+    link: `https://v3.vuejs.org/guide/migration/listeners-removed.html`
+  },
+
+  [DeprecationTypes.INSTANCE_SCOPED_SLOTS]: {
+    message: `vm.$scopedSlots has been removed. Use vm.$slots instead.`,
+    link: `https://v3.vuejs.org/guide/migration/slots-unification.html`
+  },
+
+  [DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE]: {
+    message:
+      `vm.$attrs now includes class and style bindings passed from parent. ` +
+      `Components with inheritAttrs: false will no longer auto-inherit ` +
+      `class/style on its root element. If your code relies on this behavior, ` +
+      `you may see broken styling and need to adjust your CSS. Otherwise, ` +
+      `you can disable the compat behavior and suppress this warning with:` +
+      `\n\n  configureCompat({ ${
+        DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE
+      }: false )\n`,
+    link: `https://v3.vuejs.org/guide/migration/attrs-includes-class-style.html`
+  },
+
+  [DeprecationTypes.OPTIONS_DATA_FN]: {
+    message:
+      `The "data" option can no longer be a plain object. ` +
+      `Always use a function.`,
+    link: `https://v3.vuejs.org/guide/migration/data-option.html`
+  },
+
+  [DeprecationTypes.OPTIONS_DATA_MERGE]: {
+    message: (key: string) =>
+      `Detected conflicting key "${key}" when merging data option values. ` +
+      `In Vue 3, data keys are merged shallowly and will override one another.`,
+    link: `https://v3.vuejs.org/guide/migration/data-option.html#mixin-merge-behavior-change`
+  },
+
+  [DeprecationTypes.OPTIONS_BEFORE_DESTROY]: {
+    message: `\`beforeDestroy\` has been renamed to \`beforeUnmount\`.`
+  },
+
+  [DeprecationTypes.OPTIONS_DESTROYED]: {
+    message: `\`destroyed\` has been renamed to \`unmounted\`.`
+  },
+
+  [DeprecationTypes.WATCH_ARRAY]: {
+    message:
+      `"watch" option or vm.$watch on an array value will no longer ` +
+      `trigger on array mutation unless the "deep" option is specified. ` +
+      `If current usage is intended, you can disable the compat behavior and ` +
+      `suppress this warning with:` +
+      `\n\n  configureCompat({ ${DeprecationTypes.WATCH_ARRAY}: false })\n`,
+    link: `https://v3.vuejs.org/guide/migration/watch.html`
+  },
+
+  [DeprecationTypes.PROPS_DEFAULT_THIS]: {
+    message: (key: string) =>
+      `props default value function no longer has access to "this". ` +
+      `(found in prop "${key}")`,
+    link: `https://v3.vuejs.org/guide/migration/props-default-this.html`
+  },
+
+  [DeprecationTypes.CUSTOM_DIR]: {
+    message: (legacyHook: string, newHook: string) =>
+      `Custom directive hook "${legacyHook}" has been removed. ` +
+      `Use "${newHook}" instead.`,
+    link: `https://v3.vuejs.org/guide/migration/custom-directives.html`
+  },
+
+  [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.ATTR_FALSE_VALUE]: {
+    message: (name: string) =>
+      `Attribute "${name}" with v-bind value \`false\` will render ` +
+      `${name}="false" instead of removing it in Vue 3. To remove the attribute, ` +
+      `use \`null\` or \`undefined\` instead. If the usage is intended, ` +
+      `you can disable the compat behavior and suppress this warning with:` +
+      `\n\n  configureCompat({ ${
+        DeprecationTypes.ATTR_FALSE_VALUE
+      }: false })\n`,
+    link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html`
+  },
+
+  [DeprecationTypes.ATTR_ENUMERATED_COERSION]: {
+    message: (name: string, value: any, coerced: string) =>
+      `Enumerated attribute "${name}" with v-bind value \`${value}\` will ` +
+      `${
+        value === null ? `be removed` : `render the value as-is`
+      } instead of coercing the value to "${coerced}" in Vue 3. ` +
+      `Always use explicit "true" or "false" values for enumerated attributes. ` +
+      `If the usage is intended, ` +
+      `you can disable the compat behavior and suppress this warning with:` +
+      `\n\n  configureCompat({ ${
+        DeprecationTypes.ATTR_ENUMERATED_COERSION
+      }: false })\n`,
+    link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html`
+  },
+
+  [DeprecationTypes.TRANSITION_CLASSES]: {
+    message: `` // this feature cannot be runtime-detected
+  },
+
+  [DeprecationTypes.TRANSITION_GROUP_ROOT]: {
+    message:
+      `<TransitionGroup> no longer renders a root <span> element by ` +
+      `default if no "tag" prop is specified. If you do not rely on the span ` +
+      `for styling, you can disable the compat behavior and suppress this ` +
+      `warning with:` +
+      `\n\n  configureCompat({ ${
+        DeprecationTypes.TRANSITION_GROUP_ROOT
+      }: false })\n`,
+    link: `https://v3.vuejs.org/guide/migration/transition-group.html`
+  },
+
+  [DeprecationTypes.COMPONENT_ASYNC]: {
+    message: (comp: any) => {
+      const name = getComponentName(comp)
+      return (
+        `Async component${
+          name ? ` <${name}>` : `s`
+        } should be explicitly created via \`defineAsyncComponent()\` ` +
+        `in Vue 3. Plain functions will be treated as functional components in ` +
+        `non-compat build. If you have already migrated all async component ` +
+        `usage and intend to use plain functions for functional components, ` +
+        `you can disable the compat behavior and suppress this ` +
+        `warning with:` +
+        `\n\n  configureCompat({ ${
+          DeprecationTypes.COMPONENT_ASYNC
+        }: false })\n`
+      )
+    },
+    link: `https://v3.vuejs.org/guide/migration/async-components.html`
+  },
+
+  [DeprecationTypes.COMPONENT_FUNCTIONAL]: {
+    message: (comp: any) => {
+      const name = getComponentName(comp)
+      return (
+        `Functional component${
+          name ? ` <${name}>` : `s`
+        } should be defined as a plain function in Vue 3. The "functional" ` +
+        `option has been removed. NOTE: Before migrating to use plain ` +
+        `functions for functional components, first make sure that all async ` +
+        `components usage have been migrated and its compat behavior has ` +
+        `been disabled.`
+      )
+    },
+    link: `https://v3.vuejs.org/guide/migration/functional-components.html`
+  },
+
+  [DeprecationTypes.COMPONENT_V_MODEL]: {
+    message: (comp: ComponentOptions) => {
+      const configMsg =
+        `opt-in to ` +
+        `Vue 3 behavior on a per-component basis with \`compatConfig: { ${
+          DeprecationTypes.COMPONENT_V_MODEL
+        }: false }\`.`
+      if (
+        comp.props && isArray(comp.props)
+          ? comp.props.includes('modelValue')
+          : hasOwn(comp.props, 'modelValue')
+      ) {
+        return (
+          `Component delcares "modelValue" prop, which is Vue 3 usage, but ` +
+          `is running under Vue 2 compat v-model behavior. You can ${configMsg}`
+        )
+      }
+      return (
+        `v-model usage on component has changed in Vue 3. Component that expects ` +
+        `to work with v-model should now use the "modelValue" prop and emit the ` +
+        `"update:modelValue" event. You can update the usage and then ${configMsg}`
+      )
+    },
+    link: `https://v3.vuejs.org/guide/migration/v-model.html`
+  },
+
+  [DeprecationTypes.RENDER_FUNCTION]: {
+    message:
+      `Vue 3's render function API has changed. ` +
+      `You can opt-in to the new API with:` +
+      `\n\n  configureCompat({ ${
+        DeprecationTypes.RENDER_FUNCTION
+      }: false })\n` +
+      `\n  (This can also be done per-component via the "compatConfig" option.)`,
+    link: `https://v3.vuejs.org/guide/migration/render-function-api.html`
+  }
+}
+
+const instanceWarned: Record<string, true> = Object.create(null)
+const warnCount: Record<string, number> = Object.create(null)
+
+export function warnDeprecation(
+  key: DeprecationTypes,
+  instance: ComponentInternalInstance | null,
+  ...args: any[]
+) {
+  if (!__DEV__) {
+    return
+  }
+
+  instance = instance || getCurrentInstance()
+
+  // check user config
+  const config = getCompatConfigForKey(key, instance)
+  if (config === 'suppress-warning') {
+    return
+  }
+
+  const dupKey = key + args.join('')
+  const compName = instance && formatComponentName(instance, instance.type)
+
+  // skip if the same warning is emitted for the same component type
+  if (compName !== `Anonymous`) {
+    const componentDupKey = dupKey + compName
+    if (componentDupKey in instanceWarned) {
+      return
+    }
+    instanceWarned[componentDupKey] = true
+  }
+
+  // same warning, but different component. skip the long message and just
+  // log the key and count.
+  if (dupKey in warnCount) {
+    warn(`(deprecation ${key}) (${++warnCount[dupKey] + 1})`)
+    return
+  }
+
+  warnCount[dupKey] = 0
+
+  const { message, link } = deprecationData[key]
+  warn(
+    `(deprecation ${key}) ${
+      typeof message === 'function' ? message(...args) : message
+    }${link ? `\n  Details: ${link}` : ``}`
+  )
+  if (!isCompatEnabled(key, instance)) {
+    console.error(
+      `^ The above deprecation's compat behavior is disabled and will likely ` +
+        `lead to runtime errors.`
+    )
+  }
+}
 
 export type CompatConfig = Partial<
   Record<DeprecationTypes, boolean | 'suppress-warning'>
index d7747789155be9479927fa08eff5eb0caf28d60d..0cae7ad38421f53e6b5cd2fe54347e06815fa08e 100644 (file)
@@ -10,8 +10,11 @@ import {
 import { resolveInjections } from '../componentOptions'
 import { InternalSlots } from '../componentSlots'
 import { isVNode } from '../vnode'
-import { checkCompatEnabled, softAssertCompatEnabled } from './compatConfig'
-import { DeprecationTypes } from './deprecations'
+import {
+  checkCompatEnabled,
+  softAssertCompatEnabled,
+  DeprecationTypes
+} from './compatConfig'
 import { getCompatListeners } from './instanceListeners'
 import { compatH } from './renderFn'
 
index f6303c4e68d86f2e57564d787a834945a6b0206d..dc854dbcaaf968c6352a79929c8763bf11440e6f 100644 (file)
@@ -1,8 +1,7 @@
 import { isArray } from '@vue/shared'
 import { ComponentInternalInstance } from '../component'
 import { ObjectDirective, DirectiveHook } from '../directives'
-import { softAssertCompatEnabled } from './compatConfig'
-import { DeprecationTypes } from './deprecations'
+import { softAssertCompatEnabled, DeprecationTypes } from './compatConfig'
 
 export interface LegacyDirective {
   bind?: DirectiveHook
index c296b460a65679f60279f575d331483a9eb3fafd..87663dbd03665d1ae906f8460162351a9537bacc 100644 (file)
@@ -1,6 +1,6 @@
 import { isPlainObject } from '@vue/shared'
 import { ComponentInternalInstance } from '../component'
-import { DeprecationTypes, warnDeprecation } from './deprecations'
+import { DeprecationTypes, warnDeprecation } from './compatConfig'
 
 export function deepMergeData(
   to: any,
diff --git a/packages/runtime-core/src/compat/deprecations.ts b/packages/runtime-core/src/compat/deprecations.ts
deleted file mode 100644 (file)
index f33f360..0000000
+++ /dev/null
@@ -1,449 +0,0 @@
-import { hasOwn, isArray } from '@vue/shared'
-import {
-  ComponentInternalInstance,
-  ComponentOptions,
-  formatComponentName,
-  getComponentName,
-  getCurrentInstance,
-  isRuntimeOnly
-} from '../component'
-import { warn } from '../warning'
-import { getCompatConfigForKey, isCompatEnabled } from './compatConfig'
-
-export const enum DeprecationTypes {
-  GLOBAL_MOUNT = 'GLOBAL_MOUNT',
-  GLOBAL_MOUNT_CONTAINER = 'GLOBAL_MOUNT_CONTAINER',
-  GLOBAL_EXTEND = 'GLOBAL_EXTEND',
-  GLOBAL_PROTOTYPE = 'GLOBAL_PROTOTYPE',
-  GLOBAL_SET = 'GLOBAL_SET',
-  GLOBAL_DELETE = 'GLOBAL_DELETE',
-  GLOBAL_OBSERVABLE = 'GLOBAL_OBSERVABLE',
-  GLOBAL_UTIL = 'GLOBAL_UTIL',
-
-  CONFIG_SILENT = 'CONFIG_SILENT',
-  CONFIG_DEVTOOLS = 'CONFIG_DEVTOOLS',
-  CONFIG_KEY_CODES = 'CONFIG_KEY_CODES',
-  CONFIG_PRODUCTION_TIP = 'CONFIG_PRODUCTION_TIP',
-  CONFIG_IGNORED_ELEMENTS = 'CONFIG_IGNORED_ELEMENTS',
-
-  INSTANCE_SET = 'INSTANCE_SET',
-  INSTANCE_DELETE = 'INSTANCE_DELETE',
-  INSTANCE_DESTROY = 'INSTANCE_DESTROY',
-  INSTANCE_EVENT_EMITTER = 'INSTANCE_EVENT_EMITTER',
-  INSTANCE_EVENT_HOOKS = 'INSTANCE_EVENT_HOOKS',
-  INSTANCE_CHILDREN = 'INSTANCE_CHILDREN',
-  INSTANCE_LISTENERS = 'INSTANCE_LISTENERS',
-  INSTANCE_SCOPED_SLOTS = 'INSTANCE_SCOPED_SLOTS',
-  INSTANCE_ATTRS_CLASS_STYLE = 'INSTANCE_ATTRS_CLASS_STYLE',
-
-  OPTIONS_DATA_FN = 'OPTIONS_DATA_FN',
-  OPTIONS_DATA_MERGE = 'OPTIONS_DATA_MERGE',
-  OPTIONS_BEFORE_DESTROY = 'OPTIONS_BEFORE_DESTROY',
-  OPTIONS_DESTROYED = 'OPTIONS_DESTROYED',
-
-  WATCH_ARRAY = 'WATCH_ARRAY',
-  PROPS_DEFAULT_THIS = 'PROPS_DEFAULT_THIS',
-
-  V_ON_KEYCODE_MODIFIER = 'V_ON_KEYCODE_MODIFIER',
-  CUSTOM_DIR = 'CUSTOM_DIR',
-
-  ATTR_FALSE_VALUE = 'ATTR_FALSE_VALUE',
-  ATTR_ENUMERATED_COERSION = 'ATTR_ENUMERATED_COERSION',
-
-  TRANSITION_CLASSES = 'TRANSITION_CLASSES',
-  TRANSITION_GROUP_ROOT = 'TRANSITION_GROUP_ROOT',
-
-  COMPONENT_ASYNC = 'COMPONENT_ASYNC',
-  COMPONENT_FUNCTIONAL = 'COMPONENT_FUNCTIONAL',
-  COMPONENT_V_MODEL = 'COMPONENT_V_MODEL',
-
-  RENDER_FUNCTION = 'RENDER_FUNCTION'
-}
-
-type DeprecationData = {
-  message: string | ((...args: any[]) => string)
-  link?: string
-}
-
-const deprecationData: Record<DeprecationTypes, DeprecationData> = {
-  [DeprecationTypes.GLOBAL_MOUNT]: {
-    message:
-      `The global app bootstrapping 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.GLOBAL_MOUNT_CONTAINER]: {
-    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.GLOBAL_EXTEND]: {
-    message:
-      `Vue.extend() has been removed in Vue 3. ` +
-      `Use defineComponent() instead.`,
-    link: `https://v3.vuejs.org/api/global-api.html#definecomponent`
-  },
-
-  [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_UTIL]: {
-    message:
-      `Vue.util has been removed. Please refactor to avoid its usage ` +
-      `since it was an internal API even in Vue 2.`
-  },
-
-  [DeprecationTypes.CONFIG_SILENT]: {
-    message:
-      `config.silent has been removed because it is not good practice to ` +
-      `intentionally suppress warnings. You can use your browser console's ` +
-      `filter features to focus on relevant messages.`
-  },
-
-  [DeprecationTypes.CONFIG_DEVTOOLS]: {
-    message:
-      `config.devtools has been removed. To enable devtools for ` +
-      `production, configure the __VUE_PROD_DEVTOOLS__ compile-time flag.`,
-    link: `https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags`
-  },
-
-  [DeprecationTypes.CONFIG_KEY_CODES]: {
-    message:
-      `config.keyCodes has been removed. ` +
-      `In Vue 3, you can directly use the kebab-case key names as v-on modifiers.`,
-    link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html`
-  },
-
-  [DeprecationTypes.CONFIG_PRODUCTION_TIP]: {
-    message: `config.productionTip has been removed.`,
-    link: `https://v3.vuejs.org/guide/migration/global-api.html#config-productiontip-removed`
-  },
-
-  [DeprecationTypes.CONFIG_IGNORED_ELEMENTS]: {
-    message: () => {
-      let msg = `config.ignoredElements has been removed.`
-      if (isRuntimeOnly()) {
-        msg += ` Pass the "isCustomElement" option to @vue/compiler-dom instead.`
-      } else {
-        msg += ` Use config.isCustomElement instead.`
-      }
-      return msg
-    },
-    link: `https://v3.vuejs.org/guide/migration/global-api.html#config-ignoredelements-is-now-config-iscustomelement`
-  },
-
-  [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_DESTROY]: {
-    message: `vm.$destroy() has been removed. Use app.unmount() instead.`,
-    link: `https://v3.vuejs.org/api/application-api.html#unmount`
-  },
-
-  [DeprecationTypes.INSTANCE_EVENT_EMITTER]: {
-    message:
-      `vm.$on/$once/$off() have been removed. ` +
-      `Use an external event emitter library instead.`,
-    link: `https://v3.vuejs.org/guide/migration/events-api.html`
-  },
-
-  [DeprecationTypes.INSTANCE_EVENT_HOOKS]: {
-    message:
-      `"hook:x" lifecycle events are no longer supported. ` +
-      `Use Composition API to dynamically register lifecycle hooks.`,
-    link: `https://v3.vuejs.org/api/composition-api.html#lifecycle-hooks`
-  },
-
-  [DeprecationTypes.INSTANCE_CHILDREN]: {
-    message:
-      `vm.$children has been removed. Consider refactoring your logic ` +
-      `to avoid relying on direct access to child components.`,
-    link: `https://v3.vuejs.org/guide/migration/children.html`
-  },
-
-  [DeprecationTypes.INSTANCE_LISTENERS]: {
-    message:
-      `vm.$listeners has been removed. Parent v-on listeners are now ` +
-      `included in vm.$attrs and it is no longer necessary to separately use ` +
-      `v-on="$listeners" if you are already using v-bind="$attrs".`,
-    link: `https://v3.vuejs.org/guide/migration/listeners-removed.html`
-  },
-
-  [DeprecationTypes.INSTANCE_SCOPED_SLOTS]: {
-    message: `vm.$scopedSlots has been removed. Use vm.$slots instead.`,
-    link: `https://v3.vuejs.org/guide/migration/slots-unification.html`
-  },
-
-  [DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE]: {
-    message:
-      `vm.$attrs now includes class and style bindings passed from parent. ` +
-      `Components with inheritAttrs: false will no longer auto-inherit ` +
-      `class/style on its root element. If your code relies on this behavior, ` +
-      `you may see broken styling and need to adjust your CSS. Otherwise, ` +
-      `you can disable the compat behavior and suppress this warning with:` +
-      `\n\n  configureCompat({ ${
-        DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE
-      }: false )\n`,
-    link: `https://v3.vuejs.org/guide/migration/attrs-includes-class-style.html`
-  },
-
-  [DeprecationTypes.OPTIONS_DATA_FN]: {
-    message:
-      `The "data" option can no longer be a plain object. ` +
-      `Always use a function.`,
-    link: `https://v3.vuejs.org/guide/migration/data-option.html`
-  },
-
-  [DeprecationTypes.OPTIONS_DATA_MERGE]: {
-    message: (key: string) =>
-      `Detected conflicting key "${key}" when merging data option values. ` +
-      `In Vue 3, data keys are merged shallowly and will override one another.`,
-    link: `https://v3.vuejs.org/guide/migration/data-option.html#mixin-merge-behavior-change`
-  },
-
-  [DeprecationTypes.OPTIONS_BEFORE_DESTROY]: {
-    message: `\`beforeDestroy\` has been renamed to \`beforeUnmount\`.`
-  },
-
-  [DeprecationTypes.OPTIONS_DESTROYED]: {
-    message: `\`destroyed\` has been renamed to \`unmounted\`.`
-  },
-
-  [DeprecationTypes.WATCH_ARRAY]: {
-    message:
-      `"watch" option or vm.$watch on an array value will no longer ` +
-      `trigger on array mutation unless the "deep" option is specified. ` +
-      `If current usage is intended, you can disable the compat behavior and ` +
-      `suppress this warning with:` +
-      `\n\n  configureCompat({ ${DeprecationTypes.WATCH_ARRAY}: false })\n`,
-    link: `https://v3.vuejs.org/guide/migration/watch.html`
-  },
-
-  [DeprecationTypes.PROPS_DEFAULT_THIS]: {
-    message: (key: string) =>
-      `props default value function no longer has access to "this". ` +
-      `(found in prop "${key}")`,
-    link: `https://v3.vuejs.org/guide/migration/props-default-this.html`
-  },
-
-  [DeprecationTypes.CUSTOM_DIR]: {
-    message: (legacyHook: string, newHook: string) =>
-      `Custom directive hook "${legacyHook}" has been removed. ` +
-      `Use "${newHook}" instead.`,
-    link: `https://v3.vuejs.org/guide/migration/custom-directives.html`
-  },
-
-  [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.ATTR_FALSE_VALUE]: {
-    message: (name: string) =>
-      `Attribute "${name}" with v-bind value \`false\` will render ` +
-      `${name}="false" instead of removing it in Vue 3. To remove the attribute, ` +
-      `use \`null\` or \`undefined\` instead. If the usage is intended, ` +
-      `you can disable the compat behavior and suppress this warning with:` +
-      `\n\n  configureCompat({ ${
-        DeprecationTypes.ATTR_FALSE_VALUE
-      }: false })\n`,
-    link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html`
-  },
-
-  [DeprecationTypes.ATTR_ENUMERATED_COERSION]: {
-    message: (name: string, value: any, coerced: string) =>
-      `Enumerated attribute "${name}" with v-bind value \`${value}\` will ` +
-      `${
-        value === null ? `be removed` : `render the value as-is`
-      } instead of coercing the value to "${coerced}" in Vue 3. ` +
-      `Always use explicit "true" or "false" values for enumerated attributes. ` +
-      `If the usage is intended, ` +
-      `you can disable the compat behavior and suppress this warning with:` +
-      `\n\n  configureCompat({ ${
-        DeprecationTypes.ATTR_ENUMERATED_COERSION
-      }: false })\n`,
-    link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html`
-  },
-
-  [DeprecationTypes.TRANSITION_CLASSES]: {
-    message: `` // this feature cannot be runtime-detected
-  },
-
-  [DeprecationTypes.TRANSITION_GROUP_ROOT]: {
-    message:
-      `<TransitionGroup> no longer renders a root <span> element by ` +
-      `default if no "tag" prop is specified. If you do not rely on the span ` +
-      `for styling, you can disable the compat behavior and suppress this ` +
-      `warning with:` +
-      `\n\n  configureCompat({ ${
-        DeprecationTypes.TRANSITION_GROUP_ROOT
-      }: false })\n`,
-    link: `https://v3.vuejs.org/guide/migration/transition-group.html`
-  },
-
-  [DeprecationTypes.COMPONENT_ASYNC]: {
-    message: (comp: any) => {
-      const name = getComponentName(comp)
-      return (
-        `Async component${
-          name ? ` <${name}>` : `s`
-        } should be explicitly created via \`defineAsyncComponent()\` ` +
-        `in Vue 3. Plain functions will be treated as functional components in ` +
-        `non-compat build. If you have already migrated all async component ` +
-        `usage and intend to use plain functions for functional components, ` +
-        `you can disable the compat behavior and suppress this ` +
-        `warning with:` +
-        `\n\n  configureCompat({ ${
-          DeprecationTypes.COMPONENT_ASYNC
-        }: false })\n`
-      )
-    },
-    link: `https://v3.vuejs.org/guide/migration/async-components.html`
-  },
-
-  [DeprecationTypes.COMPONENT_FUNCTIONAL]: {
-    message: (comp: any) => {
-      const name = getComponentName(comp)
-      return (
-        `Functional component${
-          name ? ` <${name}>` : `s`
-        } should be defined as a plain function in Vue 3. The "functional" ` +
-        `option has been removed. NOTE: Before migrating to use plain ` +
-        `functions for functional components, first make sure that all async ` +
-        `components usage have been migrated and its compat behavior has ` +
-        `been disabled.`
-      )
-    },
-    link: `https://v3.vuejs.org/guide/migration/functional-components.html`
-  },
-
-  [DeprecationTypes.COMPONENT_V_MODEL]: {
-    message: (comp: ComponentOptions) => {
-      const configMsg =
-        `opt-in to ` +
-        `Vue 3 behavior on a per-component basis with \`compatConfig: { ${
-          DeprecationTypes.COMPONENT_V_MODEL
-        }: false }\`.`
-      if (
-        comp.props && isArray(comp.props)
-          ? comp.props.includes('modelValue')
-          : hasOwn(comp.props, 'modelValue')
-      ) {
-        return (
-          `Component delcares "modelValue" prop, which is Vue 3 usage, but ` +
-          `is running under Vue 2 compat v-model behavior. You can ${configMsg}`
-        )
-      }
-      return (
-        `v-model usage on component has changed in Vue 3. Component that expects ` +
-        `to work with v-model should now use the "modelValue" prop and emit the ` +
-        `"update:modelValue" event. You can update the usage and then ${configMsg}`
-      )
-    },
-    link: `https://v3.vuejs.org/guide/migration/v-model.html`
-  },
-
-  [DeprecationTypes.RENDER_FUNCTION]: {
-    message:
-      `Vue 3's render function API has changed. ` +
-      `You can opt-in to the new API with:` +
-      `\n\n  configureCompat({ ${
-        DeprecationTypes.RENDER_FUNCTION
-      }: false })\n` +
-      `\n  (This can also be done per-component via the "compatConfig" option.)`,
-    link: `https://v3.vuejs.org/guide/migration/render-function-api.html`
-  }
-}
-
-const instanceWarned: Record<string, true> = Object.create(null)
-const warnCount: Record<string, number> = Object.create(null)
-
-export function warnDeprecation(
-  key: DeprecationTypes,
-  instance: ComponentInternalInstance | null,
-  ...args: any[]
-) {
-  if (!__DEV__) {
-    return
-  }
-
-  instance = instance || getCurrentInstance()
-
-  // check user config
-  const config = getCompatConfigForKey(key, instance)
-  if (config === 'suppress-warning') {
-    return
-  }
-
-  const dupKey = key + args.join('')
-  const compName = instance && formatComponentName(instance, instance.type)
-
-  // skip if the same warning is emitted for the same component type
-  if (compName !== `Anonymous`) {
-    const componentDupKey = dupKey + compName
-    if (componentDupKey in instanceWarned) {
-      return
-    }
-    instanceWarned[componentDupKey] = true
-  }
-
-  // same warning, but different component. skip the long message and just
-  // log the key and count.
-  if (dupKey in warnCount) {
-    warn(`(deprecation ${key}) (${++warnCount[dupKey] + 1})`)
-    return
-  }
-
-  warnCount[dupKey] = 0
-
-  const { message, link } = deprecationData[key]
-  warn(
-    `(deprecation ${key}) ${
-      typeof message === 'function' ? message(...args) : message
-    }${link ? `\n  Details: ${link}` : ``}`
-  )
-  if (!isCompatEnabled(key, instance)) {
-    console.error(
-      `^ The above deprecation's compat behavior is disabled and will likely ` +
-        `lead to runtime errors.`
-    )
-  }
-}
index 13cb05c8030c583b681c68cc1afb266a22b80f7a..de89c0a90a5ae9a52513540fedc5862a2596cd37 100644 (file)
@@ -39,11 +39,12 @@ import { ComponentPublicInstance } from '../componentPublicInstance'
 import { devtoolsInitApp } from '../devtools'
 import { Directive } from '../directives'
 import { nextTick } from '../scheduler'
-import { warnDeprecation, DeprecationTypes } from './deprecations'
 import { version } from '..'
 import { LegacyConfig } from './globalConfig'
 import { LegacyDirective } from './customDirective'
 import {
+  warnDeprecation,
+  DeprecationTypes,
   assertCompatEnabled,
   configureCompat,
   isCompatEnabled,
index fab0196fa839ba0123d7292bd5a57828448992a3..bed3fc39ea97c6f8eae16e565b2a2b88df4c6e6e 100644 (file)
@@ -1,9 +1,12 @@
 import { extend, isArray, isString } from '@vue/shared'
 import { AppConfig } from '../apiCreateApp'
 import { isRuntimeOnly } from '../component'
-import { isCompatEnabled } from './compatConfig'
 import { deepMergeData } from './data'
-import { DeprecationTypes, warnDeprecation } from './deprecations'
+import {
+  DeprecationTypes,
+  warnDeprecation,
+  isCompatEnabled
+} from './compatConfig'
 import { isCopyingConfig } from './global'
 
 // legacy config warnings
index 2f9c254df899c2c93bffec734a8ac5cf429d3261..60144fa6f32da023444ba8c3764a2f620b892553 100644 (file)
@@ -2,11 +2,11 @@ import { extend, NOOP } from '@vue/shared'
 import { PublicPropertiesMap } from '../componentPublicInstance'
 import { getCompatChildren } from './instanceChildren'
 import {
+  DeprecationTypes,
   assertCompatEnabled,
   checkCompatEnabled,
   isCompatEnabled
 } from './compatConfig'
-import { DeprecationTypes } from './deprecations'
 import { off, on, once } from './instanceEventEmitter'
 import { getCompatListeners } from './instanceListeners'
 import { shallowReadonly } from '@vue/reactivity'
index 09bb4a9fef3bab7db79aaeca2a1c016382538971..349b5a3fcbd7c184e8ee52b7bd161c48d6411167 100644 (file)
@@ -2,8 +2,7 @@ import { ShapeFlags } from '@vue/shared/src'
 import { ComponentInternalInstance } from '../component'
 import { ComponentPublicInstance } from '../componentPublicInstance'
 import { VNode } from '../vnode'
-import { assertCompatEnabled } from './compatConfig'
-import { DeprecationTypes } from './deprecations'
+import { assertCompatEnabled, DeprecationTypes } from './compatConfig'
 
 export function getCompatChildren(
   instance: ComponentInternalInstance
index 0e1307badb6efea2ea7999f7e5edcda6c373a606..64237e91654c630105a9b36dd8d041d3a9db7fbe 100644 (file)
@@ -1,8 +1,7 @@
 import { isArray } from '@vue/shared'
 import { ComponentInternalInstance } from '../component'
 import { callWithAsyncErrorHandling, ErrorCodes } from '../errorHandling'
-import { assertCompatEnabled } from './compatConfig'
-import { DeprecationTypes } from './deprecations'
+import { assertCompatEnabled, DeprecationTypes } from './compatConfig'
 
 interface EventRegistry {
   [event: string]: Function[] | undefined
@@ -32,7 +31,11 @@ export function on(
     event.forEach(e => on(instance, e, fn))
   } else {
     if (event.startsWith('hook:')) {
-      assertCompatEnabled(DeprecationTypes.INSTANCE_EVENT_HOOKS, instance)
+      assertCompatEnabled(
+        DeprecationTypes.INSTANCE_EVENT_HOOKS,
+        instance,
+        event
+      )
     } else {
       assertCompatEnabled(DeprecationTypes.INSTANCE_EVENT_EMITTER, instance)
     }
index 263d19611fbc9d5c1b908d180769e19d9b34d6ac..973d440b10c6802c8418e0c6f022896a646050fa 100644 (file)
@@ -1,7 +1,6 @@
 import { isOn } from '@vue/shared'
 import { ComponentInternalInstance } from '../component'
-import { assertCompatEnabled } from './compatConfig'
-import { DeprecationTypes } from './deprecations'
+import { assertCompatEnabled, DeprecationTypes } from './compatConfig'
 
 export function getCompatListeners(instance: ComponentInternalInstance) {
   assertCompatEnabled(DeprecationTypes.INSTANCE_LISTENERS, instance)
index 48d75fa52b10459d1431a683e2ee08222cfecdd3..51871562d1af62e7b7b2b28e12880f0b255070c8 100644 (file)
@@ -1,4 +1,4 @@
-import { DeprecationTypes, warnDeprecation } from './deprecations'
+import { DeprecationTypes, warnDeprecation } from './compatConfig'
 
 export function createPropsDefaultThis(propKey: string) {
   return new Proxy(
index 945c2c2fdfa43e435c10a548cc9b6f3373b894f5..458d9e4e52b93315daa458794a25bd2658372650 100644 (file)
@@ -27,8 +27,7 @@ import {
   VNodeArrayChildren,
   VNodeProps
 } from '../vnode'
-import { checkCompatEnabled } from './compatConfig'
-import { DeprecationTypes } from './deprecations'
+import { checkCompatEnabled, DeprecationTypes } from './compatConfig'
 
 export function convertLegacyRenderFn(instance: ComponentInternalInstance) {
   const Component = instance.type as ComponentOptions
index d0d8c6af8913cd4cdbaa41263b7f64143b2e06c1..c359d17c87a5fda8d062a7b6bf4615ae3e3d25b0 100644 (file)
@@ -3,8 +3,11 @@ import { ComponentInternalInstance, ComponentOptions } from '../component'
 import { callWithErrorHandling, ErrorCodes } from '../errorHandling'
 import { VNode } from '../vnode'
 import { popWarningContext, pushWarningContext } from '../warning'
-import { isCompatEnabled } from './compatConfig'
-import { DeprecationTypes, warnDeprecation } from './deprecations'
+import {
+  DeprecationTypes,
+  warnDeprecation,
+  isCompatEnabled
+} from './compatConfig'
 
 const defaultModelMapping = {
   prop: 'value',
index 3ba0b9d3978cef179cde7b4f6401c29955d28a2f..be38504bbbe00e62805727719e9ed955b6d0cbf5 100644 (file)
@@ -66,7 +66,7 @@ import { VNodeChild } from './vnode'
 import { callWithAsyncErrorHandling } from './errorHandling'
 import { UnionToIntersection } from './helpers/typeUtils'
 import { deepMergeData } from './compat/data'
-import { DeprecationTypes } from './compat/deprecations'
+import { DeprecationTypes } from './compat/compatConfig'
 import {
   CompatConfig,
   isCompatEnabled,
index 46a6b5ef4973c4017145d4761956d2a95c41ccd0..1a789b6693511d65e6c1b6f1769ba5e95f350487 100644 (file)
@@ -34,8 +34,8 @@ import { isEmitListener } from './componentEmits'
 import { InternalObjectKey } from './vnode'
 import { AppContext } from './apiCreateApp'
 import { createPropsDefaultThis } from './compat/props'
-import { isCompatEnabled } from './compat/compatConfig'
-import { DeprecationTypes } from './compat/deprecations'
+import { isCompatEnabled, softAssertCompatEnabled } from './compat/compatConfig'
+import { DeprecationTypes } from './compat/compatConfig'
 
 export type ComponentPropsOptions<P = Data> =
   | ComponentObjectPropsOptions<P>
@@ -296,6 +296,15 @@ function setFullProps(
       if (isReservedProp(key)) {
         continue
       }
+
+      if (__COMPAT__ && key.startsWith('onHook:')) {
+        softAssertCompatEnabled(
+          DeprecationTypes.INSTANCE_EVENT_HOOKS,
+          instance,
+          key.slice(2).toLowerCase()
+        )
+      }
+
       const value = rawProps[key]
       // prop option names are camelized during normalization, so to support
       // kebab -> camel conversion here we need to camelize the key.
index 9949ca3988acb997002710496bdd87ac3768296c..42c5481bb04c4a4357fa16ea0c6b064fd312c152 100644 (file)
@@ -282,11 +282,11 @@ export const ssrUtils = (__NODE_JS__ ? _ssrUtils : null) as typeof _ssrUtils
 
 // 2.x COMPAT ------------------------------------------------------------------
 
-export { DeprecationTypes } from './compat/deprecations'
+export { DeprecationTypes } from './compat/compatConfig'
 export { CompatVue } from './compat/global'
 export { LegacyConfig } from './compat/globalConfig'
 
-import { warnDeprecation } from './compat/deprecations'
+import { warnDeprecation } from './compat/compatConfig'
 import { createCompatVue } from './compat/global'
 import {
   isCompatEnabled,
index 3830258925b6de8ac44e9024c1f142cd097dd9aa..497c4b3d1af0020d6ab7b5eb8fd6a93f38551c1a 100644 (file)
@@ -86,7 +86,7 @@ import {
 import { initFeatureFlags } from './featureFlags'
 import { isAsyncWrapper } from './apiAsyncComponent'
 import { isCompatEnabled } from './compat/compatConfig'
-import { DeprecationTypes } from './compat/deprecations'
+import { DeprecationTypes } from './compat/compatConfig'
 
 export interface Renderer<HostElement = RendererElement> {
   render: RootRenderFunction<HostElement>