Vue响应式理解

官方解释:

当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。

不是在data上添加的属性,因为在实例化是没有使用Object.definePrototype设置属性的getter/setter,watcher没有创建这些属性的依赖,所以当数据变化时,无法获取到数据更改的通知,也就不能触发视图re-render。

查看vue的源代码,加载源代码后,会首先调用initMixin构建Vue。只有当使用new实例化Vue时才会调用_init,并且这时options里的data还只是原生对象

接着调用initState,用来初始化一些需要响应式式处理的数据,方法。包含props,data,computed,watch,methods(将方法的对象设置为当前vue实例,并且判断方法名是否和props有重复的)。

如果options参数里没有data,就默认给一个空的,然后直接调用observe对data里的属性创建观察者实例

调用initData,做数据检查,是否是原生对象,检查data对象里的属性是否和props对象的属性有重合的。然后调用observe(),对data对象里的每个属性创建一个观察者对象。

调用Observer回调函数(保证每个Vue实例/组件的data都是独立的,不会造成作用域污染),定义观察者类,一旦被观察者对象应用了Observer类,就会将对象的每个属性设置成getter/setter,从而收集依赖和触发更新

调用def方法,这个方法的作用就是最后执行Object.definePrototype,将每个data里的属性设置为getter/setter。

至此,所有具有响应式的属性都在initState被初始化了和监听了。

如果想要动态添加数据到data对象上,就需要用到Vue.set方法,首先会判断是否是数据,然后如果对象上存在属性(key)就直接设置target[key] = val;接着检查是否是Vue实例,是否应被设置为观察者对象;只有已经被设置为观察者对象的对象,才能调用Vue.set动态添加属性和值;这也就是管网API上说的

注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象。

 

posted @ 2018-04-11 15:37  The_Wind_Rises  阅读(2067)  评论(0编辑  收藏  举报