vue 的 data 属性为什么是一个函数而不是一个对象?
J-DuYa opened this issue · comments
在 Vue2 版本中,组件中是不允许使用对象的方式定义 data 的,一旦用对象的方式定义 data 就会出现控制台报错的情况。
warn(
'The "data" option should be a function ' +
'that returns a per-instance value in component ' +
'definitions.',
vm
)
在根实例被创建的时候,可以是一个函数或者一个对象,源代码如下:
// core/instance/state.ts 128 行
function initData(vm: Component) {
let data: any = vm.$options.data
data = vm._data = isFunction(data) ? getData(data, vm) : data || {}
if (!isPlainObject(data)) {
data = {}
__DEV__ &&
warn(
'data functions should return an object:\n' +
'https://v2.vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
vm
)
}
// proxy data on instance
const keys = Object.keys(data)
const props = vm.$options.props
const methods = vm.$options.methods
let i = keys.length
while (i--) {
const key = keys[i]
if (__DEV__) {
if (methods && hasOwn(methods, key)) {
warn(`Method "${key}" has already been defined as a data property.`, vm)
}
}
if (props && hasOwn(props, key)) {
__DEV__ &&
warn(
`The data property "${key}" is already declared as a prop. ` +
`Use prop default value instead.`,
vm
)
} else if (!isReserved(key)) {
proxy(vm, `_data`, key)
}
}
// observe data
const ob = observe(data)
ob && ob.vmCount++
}
当我们创建组件的时候,会通过 Vue.extend 进行合并,如果是对象的话,多个组件的实例会操作合并后的 data
他们指向同一个引用地址,如果某个组件修改某一个属性,那么就是针对的就是公共数据,会影响到其他组件的正常使用。