组件中
😶组件中的data为什么必须是函数
源码
src\core\instance\init.js L57 initState() => initData()
let data = vm.$options.data
data = vm._data = typeof data === 'function'
? getData(data, vm)
: data || {}
- 对象形式定义data时,多个组件中的data使用同一个对象,会造成数据污染
- 函数形式定义data时,每次初始化执行函数返回新的数据对象,多组件互相不影响
根实例中
// 根实例中data可以为对象
new Vue({
el: '#app',
data: {
foo: 'foo',
},
})
- 根实例只有一个,不需要担心数据污染问题
检测
在组件中对象形式定义data,运行时会检测报错
<div id="demo">
<h1>组件</h1>
<comp></comp>
</div>
<script>
Vue.component('comp', {
template: '<div>I am a component</div>',
data: {
counter: 1,
},
})
const app = new Vue({
el: '#demo'
})
</script>
源码
src\core\util\options.js L121
// mergeOptions 时调用
strats.data = function (
parentVal: any,
childVal: any,
vm?: Component
): ?Function {
if (!vm) {
if (childVal && typeof childVal !== 'function') {
process.env.NODE_ENV !== 'production' && warn(
'The "data" option should be a function ' +
'that returns a per-instance value in component ' +
'definitions.',
vm
)
return parentVal
}
return mergeDataOrFn(parentVal, childVal) // 1
}
return mergeDataOrFn(parentVal, childVal, vm) // 2
}
- 组件合并选项时还没有vm实例,所以会校验data是否为函数
- 只有根实例创建时vm有值,会避开校验