简述Vue的响应式原理

Vue是一个响应式的框架,响应式是指:数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。数组

那么Vue是怎么作到响应式的呢?框架

能够从两个方面来讨论:Object和Array。函数

Object

受现代JavaScript 的限制 (以及废弃 Object.observe),Vue不能检测到对象属性的添加或删除。因此Vue经过Object.defineProperty来处理数据,把属性变成getter/setter属性,由于Object.defineProperty是ES5的一个不能shim的特性,因此不支持IE8及如下。server

一、如何追踪变化:

Vue追踪变化,是把对象用Object.defineProperty把遍历对象,使用Observer类把对象的每一个属性改写成用getter/setter来设置和获取值的改变。这样Vue就能够经过触发getter和setter方法来处理数据,就能够获取数据的改变。对象

二、依赖的收集和触发

2.1 什么是依赖?ip

用到该属性的地方,就是依赖,可是Vue封装了一个watch类来看成依赖,这个watch类能通知使用该属性的全部依赖。因此Vue收集的依赖就是收集watch类。get

2.2 如何收集依赖?原型

Vue在getter方法里收集依赖,Vue把依赖解耦成一个专门的Dep类,来处理收集和触发依赖。在使用该数据的时候,便把依赖收集到Dep里。io

2.3 如何触发依赖class

在数据发生改变的setter函数里触发依赖,Vue声明的watch类,当数据发生了改变的时候,Vue通知watch数据发生变化,让watch本身去通知依赖发生改变。

三、Object的问题

Vue使用Object.defineProperty的getter和setter来把对象变成响应式的对象,可是也由于这个,Vue能监听到该Object属性值的变化,却监听不到Object增长和删除属性。因此Vue提供了两个API:vm.set和vm.delete来处理增长属性和删除属性。

Array

Vue对象是经过getter/setter 来监听到对象的数据变化从而让对象变成响应式的。可是在数组里,有一些原型上的方法好比push,pop,shift…等,并不会触发getter/setter 就能够改变数组的值,Vue在这个时候,就没有办法进行监遵从而触发视图的改变了。

一、如何追踪变化

Vue重写了push,pop,shift,unshift,reverse,sort,splice这7个会改变Array自己的原型方法,并经过一个拦截器,把须要响应的数组,覆盖他们的原型方法。value.proto=arraysMethods.若是不支持__proto__的属性,那么Vue会暴力的把这些方法放到这些数组自己。

二、依赖的收集和触发

2.1 在哪儿收集和触发依赖

Vue对数组和对象都同样,都是在getter里收集依赖,在setter里触发依赖。

2.2 依赖放在哪儿

对象的依赖放在Dep类里,而数组的依赖放在Observer实例的Dep里。目的是为了在getter和Array的拦截器都里能访问到Observer的实例。

Vue改写了上面Object的Observer的类,给每一个属性加一个__ob__属性,经过对该属性的来判断是否响应式,且是否发生改变,从而触发依赖。

相关文章
相关标签/搜索