vue响应式
1》在上一节数据驱动的过程中,vue是如何知道data变化的(数据驱动视图的第一步)?
2》核心API:
Object.defineProperty
3》Object.defineProperty基本用法:
Object.defineProperty,get和set的用法
Get指读取属性时调用的函数。
Set指写入属性时调用的函数。
①.监听对象:
这地方要注意:当我们data.name=’xxx‘更新数据时,会直接调用set(),因为在上面说到set()是指写入属性时调用的,参数是新的值,在进行比较时,我们需要读取之前的value,此时通过get(),因为get()是读取属性时调用的。
除此之外注意上图的一行注释:value一直在闭包中,此处设置完之后,再get()也是会获取最新的值
控制台输出两次‘视图更新’,第一次data.name 第二次data.age
②.深度监听对象:
发现控制台还是只显示两次视图更新,说明还是只监听到name和age,没有监听到info address 我们该怎么办?其实只需要加一句话
解释原理,其实很简单:
第一传入defineReactive 参数value的值 分别是’张三‘ 20 和包含address的对象
当运行observe(value)函数时,由于’张三‘ 20 不是object直接return
而包含address的对象会再次遍历。
除此之外,还设置新值的地方深度监听:
4》Object.defineProperty的缺点:
①.深度监听,需要递归到底,一次性计算量大:
就比如说 我们上面的info的值是一个对象,对象的值是address,但是如果对象的值还是对象,对象的值还是对象呢。。。。,我们需要递归到底,计算量很大,容易在初始化的时候卡死
②.无法监听新增属性/删除属性,我们需要用Vue.set 和Vue.delete
③.无法原生监听数组,需要特殊处理:在下面会讲如何处理
5》vue如何监听数组变化:
①.准备数据:
②.
③.
④.
⑤.
控制台输出视图更新,说明成功监听
--------------------------------------------------------------------------------------------
我们最后再叙述一遍数组监听的流程:
首先准备数组:data里面新建个数组
然后observer(data)进行监听
然后data是对象形式的,所以直接在observer函数中执行遍历语句,执行到defineReactive函数
在defineReactive函数中执行深度监听,若value不是数组和对象,则执行Object.defineProperty函数,若是对象,则继续深度监听直到监听到基本类型,上面也讲到了,若value是数组,则执行判断语句
if(Array.isArray(target)),改变数组的隐式原型到arrProto上
然后由下图可以知道arrProto是什么
在进行data.nums.push()时,其实调用了arrProto.push(),最最最最根本 是调用了Array.prototype里面的push方法。