vue响应式

vue响应式

1》在上一节数据驱动的过程中,vue是如何知道data变化的(数据驱动视图的第一步)?

2》核心API:
Object.defineProperty

3》Object.defineProperty基本用法:
Object.defineProperty,get和set的用法
Get指读取属性时调用的函数。
Set指写入属性时调用的函数。
①.监听对象:
vue响应式
vue响应式

vue响应式

vue响应式
这地方要注意:当我们data.name=’xxx‘更新数据时,会直接调用set(),因为在上面说到set()是指写入属性时调用的,参数是新的值,在进行比较时,我们需要读取之前的value,此时通过get(),因为get()是读取属性时调用的。
除此之外注意上图的一行注释:value一直在闭包中,此处设置完之后,再get()也是会获取最新的值
vue响应式
控制台输出两次‘视图更新’,第一次data.name 第二次data.age

②.深度监听对象:
vue响应式
vue响应式
发现控制台还是只显示两次视图更新,说明还是只监听到name和age,没有监听到info address 我们该怎么办?其实只需要加一句话
vue响应式
解释原理,其实很简单:
第一传入defineReactive 参数value的值 分别是’张三‘ 20 和包含address的对象
当运行observe(value)函数时,由于’张三‘ 20 不是object直接return
而包含address的对象会再次遍历。

除此之外,还设置新值的地方深度监听:
vue响应式
vue响应式
4》Object.defineProperty的缺点:
①.深度监听,需要递归到底,一次性计算量大:
就比如说 我们上面的info的值是一个对象,对象的值是address,但是如果对象的值还是对象,对象的值还是对象呢。。。。,我们需要递归到底,计算量很大,容易在初始化的时候卡死

②.无法监听新增属性/删除属性,我们需要用Vue.set 和Vue.delete
vue响应式
③.无法原生监听数组,需要特殊处理:在下面会讲如何处理

5》vue如何监听数组变化:
①.准备数据:
vue响应式
②.
vue响应式
③.
vue响应式

④.
vue响应式

⑤.
vue响应式
控制台输出视图更新,说明成功监听

--------------------------------------------------------------------------------------------

我们最后再叙述一遍数组监听的流程:

首先准备数组:data里面新建个数组
然后observer(data)进行监听
然后data是对象形式的,所以直接在observer函数中执行遍历语句,执行到defineReactive函数
在defineReactive函数中执行深度监听,若value不是数组和对象,则执行Object.defineProperty函数,若是对象,则继续深度监听直到监听到基本类型,上面也讲到了,若value是数组,则执行判断语句
if(Array.isArray(target)),改变数组的隐式原型到arrProto上
然后由下图可以知道arrProto是什么
vue响应式
vue响应式
vue响应式
在进行data.nums.push()时,其实调用了arrProto.push(),最最最最根本 是调用了Array.prototype里面的push方法。