Vue响应式理解

官方解释:vue

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

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

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

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

若是options参数里没有data,就默认给一个空的,而后直接调用observe对data里的属性建立观察者实例server

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

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

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

至此,全部具备响应式的属性都在initState被初始化了和监听了。作用域

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

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

相关文章
相关标签/搜索