Vue的响应式——Vue源码学习总结(二)

本文详细阐述了Vue的响应式机制,包括数据驱动视图、数据劫持与依赖收集、通知依赖以及Vue中的异步队列。重点讲解了对象和数组如何变为响应式,以及nextTick在更新DOM中的作用。通过实例展示了在mounted生命周期钩子中,如何在nextTick中获取到最新的DOM数据。
摘要由CSDN通过智能技术生成

Vue的响应式

数据驱动视图:数据变化了,做一些事情让视图改变。
数据劫持:当数据被访问的时候,进行拦截,此时会进行依赖收集,数据被改变你的时候,会发送通知,告诉依赖下的watcher该执行了。
依赖收集:new watcher()中,其中会传入vm._update(vm._render())函数,在watcher中执行vm._update(vm._render()),在_render当中会访问数据,然后会被劫持,最后触发依赖收集的过程。
通知依赖:数据改变,通知依赖执行对应的渲染函数,即vm._update(vm._render()),更新视图。

关键的点:
1.对于一个对象,会递归对象,把嵌套对象(数组)以及对象中的每一个属性(数组中每一个元素,如果这个元素为对象)都变为响应式。
为什么对象本身也要变为响应式呢?(即对象本身也有一个dep对象)因为这样后面可以根据Vue.set,Vue.delete为该对象添加或者删除属性的时候可以发送知。

2.对于数组,改写了数组的push,pop,splice等可以改变原数组的方法,在保持数组原有API功能不变的情况下,增加了一个发送通知的功能。那么Vue.set,Vue.delete方法对于数组本身,其实内部就是采用了重写后的splice方法去修改数组。

3.关于vue中异步队列:首先明白一点就是数据改变后,视图是不会同步渲染的,这样开销太大。假设我使用this.msg = 1修改数据之后,下一行使用this.msg = 2再次修改数据,那么这样的话vm._update(vm._render())要执行两次,显然是不太合理的。所以在Vue中,会把需要执行的watcher放入队列当中,等到所有同步的代码执行之后,在调用这个队列中的watcher进行视图的更新。在这个队列中会进行watcher去重,因为像上面的例子,msg修改了两次,就要执行两次相同的watcher,显然是不符合道理的,所以会有一个去重的过程。其次watcher还会按id从小到大排列,因为我们在创建父子组件的时候,是先父后子,id小的为父,id大的为子,所以要进行一个从小到大的排列。

4.关于nextTick,其实就是往异步队列中push一个自定义的方法,为什么说能够在nextTick中能够拿到最新dom的数据呢?举个例子:在这个例子中
直接console.log(this.$refs.p1.textContent)是无法拿到数据的,因为这是同步代码,对于的watcher还没开始执行,dom未更新视图未渲染,所以无法拿到dom上最新的数据,如果在nextTick中却可以,因为这样的话是在队列中,也就是watcher的后面添加了一个任务,watcher执行完了才轮到这个任务,那么自然能够拿到最新的数据了。另外,这个任务队列是以微任务的方式去执行的。

mounted() {
          this.msg = "Hello World";
          this.name = "Hello snabbdom";
          this.title = "Vue.js";
		  console.log(this.$refs.p1.textContent); // 旧的数据
          Vue.nextTick(() => {
            console.log(this.$refs.p1.textContent); // 新的数据
          });
        },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值