fix(options): data options should preserve original object if possible

This commit is contained in:
Evan You 2019-10-02 10:03:43 -04:00
parent 5ab1d75c39
commit d87255ce46
10 changed files with 24 additions and 19 deletions

View File

@ -1,6 +1,6 @@
import { Component, Data, ComponentInternalInstance } from './component' import { Component, Data, ComponentInternalInstance } from './component'
import { ComponentOptions } from './componentOptions' import { ComponentOptions } from './apiOptions'
import { ComponentPublicInstance } from './componentPublicInstanceProxy' import { ComponentPublicInstance } from './componentProxy'
import { Directive } from './directives' import { Directive } from './directives'
import { RootRenderFunction } from './createRenderer' import { RootRenderFunction } from './createRenderer'
import { InjectionKey } from './apiInject' import { InjectionKey } from './apiInject'

View File

@ -4,10 +4,10 @@ import {
ComponentOptionsWithoutProps, ComponentOptionsWithoutProps,
ComponentOptionsWithArrayProps, ComponentOptionsWithArrayProps,
ComponentOptionsWithProps ComponentOptionsWithProps
} from './componentOptions' } from './apiOptions'
import { SetupContext } from './component' import { SetupContext } from './component'
import { VNodeChild } from './vnode' import { VNodeChild } from './vnode'
import { ComponentPublicInstance } from './componentPublicInstanceProxy' import { ComponentPublicInstance } from './componentProxy'
import { ExtractPropTypes } from './componentProps' import { ExtractPropTypes } from './componentProps'
import { isFunction } from '@vue/shared' import { isFunction } from '@vue/shared'

View File

@ -4,7 +4,7 @@ import {
currentInstance, currentInstance,
setCurrentInstance setCurrentInstance
} from './component' } from './component'
import { ComponentPublicInstance } from './componentPublicInstanceProxy' import { ComponentPublicInstance } from './componentProxy'
import { callWithAsyncErrorHandling, ErrorTypeStrings } from './errorHandling' import { callWithAsyncErrorHandling, ErrorTypeStrings } from './errorHandling'
import { warn } from './warning' import { warn } from './warning'
import { capitalize } from '@vue/shared' import { capitalize } from '@vue/shared'

View File

@ -30,7 +30,8 @@ import { DebuggerEvent, reactive } from '@vue/reactivity'
import { ComponentPropsOptions, ExtractPropTypes } from './componentProps' import { ComponentPropsOptions, ExtractPropTypes } from './componentProps'
import { Directive } from './directives' import { Directive } from './directives'
import { VNodeChild } from './vnode' import { VNodeChild } from './vnode'
import { ComponentPublicInstance } from './componentPublicInstanceProxy' import { ComponentPublicInstance } from './componentProxy'
import { warn } from './warning'
interface ComponentOptionsBase< interface ComponentOptionsBase<
Props, Props,
@ -231,11 +232,15 @@ export function applyOptions(
// state options // state options
if (dataOptions) { if (dataOptions) {
const data = const data = isFunction(dataOptions) ? dataOptions.call(ctx) : dataOptions
instance.data === EMPTY_OBJ if (!isObject(data)) {
? (instance.data = reactive({})) __DEV__ && warn(`data() should return an object.`)
: instance.data } else if (instance.data === EMPTY_OBJ) {
extend(data, isFunction(dataOptions) ? dataOptions.call(ctx) : dataOptions) instance.data = reactive(data)
} else {
// existing data: this is a mixin or extends.
extend(instance.data, data)
}
} }
if (computedOptions) { if (computedOptions) {
for (const key in computedOptions) { for (const key in computedOptions) {

View File

@ -3,7 +3,7 @@ import { ReactiveEffect, reactive, readonly } from '@vue/reactivity'
import { import {
PublicInstanceProxyHandlers, PublicInstanceProxyHandlers,
ComponentPublicInstance ComponentPublicInstance
} from './componentPublicInstanceProxy' } from './componentProxy'
import { ComponentPropsOptions } from './componentProps' import { ComponentPropsOptions } from './componentProps'
import { Slots } from './componentSlots' import { Slots } from './componentSlots'
import { warn } from './warning' import { warn } from './warning'
@ -14,7 +14,7 @@ import {
} from './errorHandling' } from './errorHandling'
import { AppContext, createAppContext } from './apiApp' import { AppContext, createAppContext } from './apiApp'
import { Directive } from './directives' import { Directive } from './directives'
import { applyOptions, ComponentOptions } from './componentOptions' import { applyOptions, ComponentOptions } from './apiOptions'
import { import {
EMPTY_OBJ, EMPTY_OBJ,
isFunction, isFunction,

View File

@ -2,7 +2,7 @@ import { ComponentInternalInstance, Data } from './component'
import { nextTick } from './scheduler' import { nextTick } from './scheduler'
import { instanceWatch } from './apiWatch' import { instanceWatch } from './apiWatch'
import { EMPTY_OBJ, hasOwn } from '@vue/shared' import { EMPTY_OBJ, hasOwn } from '@vue/shared'
import { ExtracComputedReturns } from './componentOptions' import { ExtracComputedReturns } from './apiOptions'
import { UnwrapRef } from '@vue/reactivity' import { UnwrapRef } from '@vue/reactivity'
// public properties exposed on the proxy, which is used as the render context // public properties exposed on the proxy, which is used as the render context

View File

@ -42,7 +42,7 @@ import { resolveSlots } from './componentSlots'
import { ShapeFlags } from './shapeFlags' import { ShapeFlags } from './shapeFlags'
import { pushWarningContext, popWarningContext, warn } from './warning' import { pushWarningContext, popWarningContext, warn } from './warning'
import { invokeDirectiveHook } from './directives' import { invokeDirectiveHook } from './directives'
import { ComponentPublicInstance } from './componentPublicInstanceProxy' import { ComponentPublicInstance } from './componentProxy'
import { App, createAppAPI } from './apiApp' import { App, createAppAPI } from './apiApp'
import { import {
SuspenseBoundary, SuspenseBoundary,

View File

@ -17,7 +17,7 @@ import { warn } from './warning'
import { ComponentInternalInstance } from './component' import { ComponentInternalInstance } from './component'
import { currentRenderingInstance } from './componentRenderUtils' import { currentRenderingInstance } from './componentRenderUtils'
import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling' import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
import { ComponentPublicInstance } from './componentPublicInstanceProxy' import { ComponentPublicInstance } from './componentProxy'
export interface DirectiveBinding { export interface DirectiveBinding {
instance: ComponentPublicInstance | null instance: ComponentPublicInstance | null

View File

@ -15,7 +15,7 @@ import {
ComponentOptionsWithArrayProps, ComponentOptionsWithArrayProps,
ComponentOptionsWithProps, ComponentOptionsWithProps,
ComponentOptions ComponentOptions
} from './componentOptions' } from './apiOptions'
import { ExtractPropTypes } from './componentProps' import { ExtractPropTypes } from './componentProps'
// `h` is a more user-friendly version of `createVNode` that allows omitting the // `h` is a more user-friendly version of `createVNode` that allows omitting the

View File

@ -64,9 +64,9 @@ export {
ComponentOptionsWithoutProps, ComponentOptionsWithoutProps,
ComponentOptionsWithProps, ComponentOptionsWithProps,
ComponentOptionsWithArrayProps ComponentOptionsWithArrayProps
} from './componentOptions' } from './apiOptions'
export { ComponentPublicInstance } from './componentPublicInstanceProxy' export { ComponentPublicInstance } from './componentProxy'
export { RendererOptions } from './createRenderer' export { RendererOptions } from './createRenderer'
export { Slot, Slots } from './componentSlots' export { Slot, Slots } from './componentSlots'
export { Prop, PropType, ComponentPropsOptions } from './componentProps' export { Prop, PropType, ComponentPropsOptions } from './componentProps'