wip: data option compat
This commit is contained in:
parent
53b8127a9c
commit
d0da0028f2
15
packages/runtime-core/src/compat/data.ts
Normal file
15
packages/runtime-core/src/compat/data.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { isPlainObject } from '@vue/shared'
|
||||||
|
import { DeprecationTypes, warnDeprecation } from './deprecations'
|
||||||
|
|
||||||
|
export function deepMergeData(to: any, from: any) {
|
||||||
|
for (const key in from) {
|
||||||
|
const toVal = to[key]
|
||||||
|
const fromVal = from[key]
|
||||||
|
if (key in to && isPlainObject(toVal) && isPlainObject(fromVal)) {
|
||||||
|
__DEV__ && warnDeprecation(DeprecationTypes.OPTIONS_DATA_MERGE, key)
|
||||||
|
deepMergeData(toVal, fromVal)
|
||||||
|
} else {
|
||||||
|
to[key] = fromVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import { isRuntimeOnly } from '../component'
|
import { isRuntimeOnly } from '../component'
|
||||||
|
import { warn } from '../warning'
|
||||||
|
|
||||||
export const enum DeprecationTypes {
|
export const enum DeprecationTypes {
|
||||||
CONFIG_SILENT,
|
CONFIG_SILENT,
|
||||||
@ -16,11 +17,14 @@ export const enum DeprecationTypes {
|
|||||||
INSTANCE_SET,
|
INSTANCE_SET,
|
||||||
INSTANCE_DELETE,
|
INSTANCE_DELETE,
|
||||||
INSTANCE_MOUNT,
|
INSTANCE_MOUNT,
|
||||||
INSTANCE_DESTROY
|
INSTANCE_DESTROY,
|
||||||
|
|
||||||
|
OPTIONS_DATA_FN,
|
||||||
|
OPTIONS_DATA_MERGE
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeprecationData = {
|
type DeprecationData = {
|
||||||
message: string | (() => string)
|
message: string | ((...args: any[]) => string)
|
||||||
link?: string
|
link?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,17 +124,31 @@ const deprecations: Record<DeprecationTypes, DeprecationData> = {
|
|||||||
[DeprecationTypes.INSTANCE_DESTROY]: {
|
[DeprecationTypes.INSTANCE_DESTROY]: {
|
||||||
message: `vm.$destroy() has been removed. Use app.unmount() instead.`,
|
message: `vm.$destroy() has been removed. Use app.unmount() instead.`,
|
||||||
link: `https://v3.vuejs.org/api/application-api.html#unmount`
|
link: `https://v3.vuejs.org/api/application-api.html#unmount`
|
||||||
|
},
|
||||||
|
|
||||||
|
[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`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function warnDeprecation(key: DeprecationTypes) {
|
export function warnDeprecation(key: DeprecationTypes, ...args: any[]) {
|
||||||
if (!__COMPAT__ || !__DEV__) {
|
if (!__COMPAT__ || !__DEV__) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { message, link } = deprecations[key]
|
const { message, link } = deprecations[key]
|
||||||
console.warn(
|
warn(
|
||||||
`[Vue Deprecation]: ${typeof message === 'function' ? message() : message}${
|
`[DEPRECATION] ${
|
||||||
link ? `\nFor more details, see ${link}` : ``
|
typeof message === 'function' ? message(...args) : message
|
||||||
}`
|
}${link ? `\nFor more details, see ${link}` : ``}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -162,9 +162,14 @@ export function createCompatVue(
|
|||||||
if (!inlineOptions) {
|
if (!inlineOptions) {
|
||||||
return createCompatApp(options, SubVue)
|
return createCompatApp(options, SubVue)
|
||||||
} else {
|
} else {
|
||||||
|
const { el, data } = inlineOptions
|
||||||
|
if (data && !isFunction(data)) {
|
||||||
|
__DEV__ && warnDeprecation(DeprecationTypes.OPTIONS_DATA_FN)
|
||||||
|
inlineOptions.data = () => data
|
||||||
|
}
|
||||||
return createCompatApp(
|
return createCompatApp(
|
||||||
{
|
{
|
||||||
el: inlineOptions.el,
|
el,
|
||||||
extends: options,
|
extends: options,
|
||||||
mixins: [inlineOptions]
|
mixins: [inlineOptions]
|
||||||
},
|
},
|
||||||
|
@ -65,6 +65,7 @@ import { warn } from './warning'
|
|||||||
import { VNodeChild } from './vnode'
|
import { VNodeChild } from './vnode'
|
||||||
import { callWithAsyncErrorHandling } from './errorHandling'
|
import { callWithAsyncErrorHandling } from './errorHandling'
|
||||||
import { UnionToIntersection } from './helpers/typeUtils'
|
import { UnionToIntersection } from './helpers/typeUtils'
|
||||||
|
import { deepMergeData } from './compat/data'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for declaring custom options.
|
* Interface for declaring custom options.
|
||||||
@ -904,9 +905,13 @@ function resolveData(
|
|||||||
instance.data = reactive(data)
|
instance.data = reactive(data)
|
||||||
} else {
|
} else {
|
||||||
// existing data: this is a mixin or extends.
|
// existing data: this is a mixin or extends.
|
||||||
|
if (__COMPAT__) {
|
||||||
|
deepMergeData(instance.data, data)
|
||||||
|
} else {
|
||||||
extend(instance.data, data)
|
extend(instance.data, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function createWatcher(
|
function createWatcher(
|
||||||
raw: ComponentWatchOptionItem,
|
raw: ComponentWatchOptionItem,
|
||||||
|
@ -71,7 +71,7 @@ export function warn(msg: string, ...args: any[]) {
|
|||||||
resetTracking()
|
resetTracking()
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComponentTrace(): ComponentTraceStack {
|
export function getComponentTrace(): ComponentTraceStack {
|
||||||
let currentVNode: VNode | null = stack[stack.length - 1]
|
let currentVNode: VNode | null = stack[stack.length - 1]
|
||||||
if (!currentVNode) {
|
if (!currentVNode) {
|
||||||
return []
|
return []
|
||||||
|
Loading…
Reference in New Issue
Block a user