vue2 对象的响应式处理
在 Vue2 中,对象的响应式处理主要依赖于 Object.defineProperty
函数。Vue会遍历对象的所有属性,并对每个属性调用 Object.defineProperty
函数,使得这些属性能够被拦截。在每次属性被读取或者修改时,Vue 会通过依赖追踪来自动更新相关的视图。
具体实现流程如下:
- 遍历对象的所有属性
- 对每个属性调用
Object.defineProperty
函数,为该属性添加 getter 和 setter 方法 - getter 方法会返回该属性的值,并进行依赖收集,将当前的 Watcher 对象添加到该属性的依赖列表中
- setter 方法会监听该属性的变化,并触发该属性的依赖列表中所有 Watcher 对象的更新方法
对于对象嵌套对象的情况,Vue会递归遍历每一层对象,对其所有属性都进行 Object.defineProperty
函数的拦截。
需要注意的是,对于新增属性,Vue不能自动响应式地更新视图,因为 Vue 无法在运行时动态为对象添加 getter 和 setter 方法。如果需要动态添加属性,可以使用 Vue.set 或者 this.$set 方法,将新属性添加到对象中,并通知 Vue 进行响应式更新。
总的来说,Vue2 对象的响应式处理主要依赖于 Object.defineProperty
函数,通过拦截对象的属性来进行依赖追踪和自动更新视图。
vue2 数组的响应式处理
在 Vue 2 中,数组的响应式处理采用了重写数组原型对象的方式,以拦截数组方法的调用,并在调用后通知依赖更新。
具体步骤如下:
-
首先,创建一个空的数组原型对象
arrayProto
,并将其指向Array.prototype
。这样做的目的是为了不影响原生的数组方法,同时也能继承原生数组的所有方法。 -
然后,在
arrayProto
对象上增加一些可拦截的数组方法,比如push
、pop
、shift
、unshift
、splice
、sort
、reverse
。这些方法会被重写以拦截其调用。 -
接下来,在
observe
函数中,当数据为数组类型时,将数组的原型对象设置为arrayProto
,这样数组的所有方法就会被重写了。而当数据为对象类型时,则需要对对象的每一个属性进行劫持,即通过Object.defineProperty()
对属性进行设置,以便在属性发生变化时能够得到通知。 -
当调用重写后的数组方法时,比如
push
方法时,会先调用原生的push
方法,再通知依赖更新。
总的来说,Vue 2 通过重写数组原型对象来实现数组的响应式处理,而对于对象则采用了 Object.defineProperty()
方法对属性进行劫持的方式来实现响应式处理。