类型:Object | Function
限制:组件的定义只接受 function。
详细:
Vue
实例的数据对象。Vue
会递归地把 data
的 property
转换为 getter/setter
,从而让 data
的 property
能够响应数据变化。对象必须是纯粹的对象 (含有零个或多个的 key/value
对):浏览器 API
创建的原生对象,原型上的 property
会被忽略。大概来说,data
应该只能是数据 - 不推荐观察拥有状态行为的对象。
一旦观察过,你就无法在根数据对象上添加响应式 property
。因此推荐在创建实例之前,就声明所有的根级响应式 property
。
实例创建之后,可以通过 vm.$data
访问原始数据对象。Vue
实例也代理了 data
对象上所有的 property
,因此访问 vm.a 等价于访问 vm.$data.a
。
以 _ 或 $
开头的 property
不会被 Vue
实例代理,因为它们可能和 Vue
内置的 property
、API
方法冲突。你可以使用例如 vm.$data._property
的方式访问这些 property
。
当一个组件被定义,data
必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data
仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data
函数,每次创建一个新实例后,我们能够调用 data
函数,从而返回初始数据的一个全新副本数据对象。
如果需要,可以通过将 vm.$data
传入 JSON.parse(JSON.stringify(...))
得到深拷贝的原始数据对象。
var data = { a: 1 }
// 直接创建一个实例
var vm = new Vue({
data: data
})
vm.a // => 1
vm.$data === data // => true
// Vue.extend() 中 data 必须是函数
var Component = Vue.extend({
data: function () {
return { a: 1 }
}
})
注意,如果你为 data property 使用了箭头函数,则 this 不会指向这个组件的实例
,不过你仍然可以将其实例作为函数的第一个参数来访问
。
data: vm => ({ a: vm.myProp })
深入响应式原理(下面是官网上总结的:)
如何追踪变化
当你把一个普通的 JavaScript
对象传入 Vue
实例作为 data
选项,Vue
将遍历此对象所有的 property
,并使用 Object.defineProperty
把这些 property
全部转为 getter/setter
。Object.defineProperty
是 ES5
中一个无法 shim
的特性,这也就是 Vue
不支持 IE8
以及更低版本浏览器的原因。
这些 getter/setter
对用户来说是不可见的,但是在内部它们让 Vue
能够追踪依赖,在 property
被访问和修改时通知变更。这里需要注意的是不同浏览器在控制台打印数据对象时对 getter/setter
的格式化并不同,所以建议安装 vue-devtools
来获取对检查数据更加友好的用户界面。
每个组件实例都对应一个 watcher
实例,它会在组件渲染的过程中把“接触”过的数据 property
记录为依赖。之后当依赖项的 setter
触发时,会通知 watcher
,从而使它关联的组件重新渲染。