在vm身上,有两个属性$data,_data,这两个属性都指向Vue底层的真实的data对象,
通过$data,_data获取各属性值,是不会走数据代理机制的
其中:_data是框架内部使用的,可以看做是私有的
$data,这是Vue框架对外公开的一个属性
也就是说Vue框架会将data中的数据实时通过Object.defineProperty拷贝一份放在$data以及_data身上,供vm去使用
1、Vue的数据代理
(1)、基本阐述
vue将_data中的所有数据属性通过Object.defineProperty添加到vm实例上
,并且提供了getter和setter方法
,于是通过vm直接获取数据的时候就调用getter,获取_data中的值
,当修改的时候调用setter修改_data中的值
(2)数据代理有什么用呢?
既然vm上挂的属性就是_data中的数据代理,那么{{vm._data.name}}和{{name}}是等价的,{{vm_data.name='szk2'}}和{{name='szk2'}}也是等价的
所以就是为了写代码的方便,在{{}}直接写数据,或者直接修改就能操作到_data中
2、数据劫持
数据劫持就是将vue代码里我们写的data加工了一下,变成_data,让每个属性有了getter和setter
vue通过监听者observer来监听data中的数据,通过getter和setter监听者里面的方法,监听数据的读取与修改,当修改属性的时候,setter被调用,在setter方法中就会让订阅者执行重新解析模板的操作,从而改变了页面
先看看我们写的data和加工之后的data有什么区别
3、总结
数据劫持:
创建Vue实例vm,vm身上会有_data属性,_data通过劫持data配置项,再通过defineProperty的getter和setter,得到的响应式的数据。把vue中的data数据拦截改写成具有getter和setter形式的_data,就是数据劫持。
数据代理
vm中_data中的数据又通过数据代理(也是通过defineProperty的getter和setter实现),放置到vm身上,vm可以通过getter方法,setter方法直接使用_data中的数据,方便书写数据
步骤:
1-把vue实例中的data,通过Object.defineProperty的setter和getter进行数据劫持,使得data改写为到_data(使得数据改写为响应式的数据,具有getter和setter);
2-通过vm进行数据代理,代理_data