在这里我先提出两个问题(文章末尾会进行解答):
响应系统中的Watcher即这个系统的观察者,它是响应系统中观察者模式的载体,当响应系统中的数据发生改变的时候,它能够知道并且执行相应的函数以达到某种业务逻辑的目的。打个比方,如果你是一个商家,要寄一批货分别给不同的客户,那么watcher就是一个个快递员,发出的动作就是数据发生改变。你只需要负责寄出去这个动作就行了,如何找到、送到客户则是watcher的事情。
每个watcher和数据之间的关系要么是1对1,要么是多对多关系(这与watcher的类型有关),要不是没有联系。watcher和业务逻辑只有1对1关系。
在Vue源码中是没有体现出Watcher的类型的,我在这里给Watcher添加类型是为了更好地理解Watcher这个对象。Watcher在普通的业务逻辑上可以分为以下三类:
在这里多嘴一下lazy型的观察者是怎么回事吧。lazy型观察者在Vue中表现为computed属性,一般这个属性是一个函数,以下是一个例子:
computed: {
// getCount最后处理成一个属性,然后这个方法被存储在Watcher的某个属性中
getCount() {
return this.a + this.b;
}
}
lazy观察者里面有一个dirty属性,也就是一个开关作用,只有它为true的时候使用getCount的getter方法的时候,才会进行调用这个函数。
如果lazy观察者所引用的数据(a或者b属性)发生改变后,会将这个放到观察者执行队列中,然后执行这个观察者的时候把dirty赋值为true(代表下次访问getter方法的时候会执行一遍lazy的求值方法(求值后会将dirty赋值为false))。等到下一次需要获取这个数据的时候才进行求值,所以它叫做惰性求值。这种方式能够节省不必要执行函数的开支。
参考 前端vue面试题详细解答
看过Vue源码的defineReactive这个方法,就会发现一个被观察的对象里面每个属性会有一个Dep依赖筐来存放所有观察它的Watcher。而defineReactive方法只有初始化每个属性的dep却并没有创建观察者(要分清初始化和创建观察者是分开这个事实)。那么这个Dep如何添加观察者呢?Vue使用了全局变量,这个变量叫做Dep.target,它是一个Watcher类型的变量,来将Watcher和Dep进行互相绑定。数据的绑定用图来表示的话如下:
我们可以明确以下区别:
Vue是如何实现性能优化的呢?最显著的两个点:
第二个不在这里面讲解,我们看一下第一个是怎么回事?
这个队列的长度是怎么定量的呢?
它的流程是如下的:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。