手机版

Vue.js原理分析观察器模块详解

时间:2021-09-06 来源:互联网 编辑:宝哥软件园 浏览:

介绍

观察者是Vue核心中最重要的模块,可以实现视图和数据的响应更新,底层有观察者的支持。

注:本文分析[emailprotected]

Vue项目中观察者模块的代码位置为src/core/observer,模块分为以下几个部分:

Observer:数据的观察者将数据对象的读写操作置于自己的监督之下。观察器将被告知数据变化,然后观察器将执行相应的操作,例如更新视图Dep :的观察器和观察器之间的链接。当数据发生变化时,将由观察者观察,然后由DEP通知观察者。图表如下:

观察者

观察者类是在src/core src/core/Observer/index . js中定义的,我们先来看看观察者的构造函数

构造函数(value : any){ this . value=value this . Dep=new Dep()this . vmcount=0 def(value,' __ob__ ',this)if(array . isarray(value)){ const增广=hasProto?proto扩增:复制扩增(值,数组方法,数组键)这个。观察数组(值)} else {this。walk (value)}} value是一个需要观察的数据对象。在构造函数中,__ob__属性将被添加到值中,作为观察者已经观察到数据的标志。如果值是数组,则使用observeArray遍历值,并对值中的每个元素调用observe来分别进行观察。如果值是一个对象,遍历值上的每个键,并为每个键调用defineReactive以获得对该键的设置/获取控制。

解释上面使用的几个函数的功能:

ObserveArray:遍历数组,并在数组的每个元素上调用ObserveObserveObserve3360来检查对象上是否有__ob__属性。如果存在,则表示该物体已被观察者观察到。如果不存在,新观察者会观察对象(其实有一些判断逻辑,为了方便理解,我就不赘述了。)walk:遍历对象的每一个键,调用Define Reactive Define Reactive 3360通过Object.defineProperty设置对象的键属性,这样就可以捕获属性值的set/get动作。通常,获取操作由观察者的实例对象执行。此时,观察者的实例对象将自动添加到Dep实例的依赖数组中。当集合由外部操作触发时,将通过Dep实例的notify通知所有依赖观察器进行更新。如果你不太理解上面的文字描述,可以看看图片:

Dep

Dep是观察者和观察者之间的链接,Dep也可以看作是服务于观察者的订阅系统。观察者订阅观察者的Dep,当观察者观察到的数据发生变化时,所有订阅的观察者都会通过Dep得到通知。

Dep提供了几个接口:

AddSub:接收一个Watcher实例作为参数,并将该Watcher实例存储在记录所依赖的数组中。removeSub:对应于addSub,用于从记录所依赖的数组中移除Watcher实例。目前需要操作的Watcher实例存储在depend: Dep.target上,调用depend将调用Watcher实例的addDep方法。addDep的功能可以在Watcher的介绍中看到。notify:通知依赖数组中的所有观察器更新观察器

Watcher用于订阅数据中的更改并执行相应的操作(如更新视图)。观察者的构造函数定义如下:

构造函数(vm、expOrFn、cb、options){ this。虚拟机=虚拟机虚拟机._观察者。push(this)//options if(options){ this。deep=!options.deep this.user=!options.user this.lazy=!options.lazy this.sync=!选项。同步} else { this。深度=这个。用户=这个。懒惰=这个。sync=false }这。CB=CB这个。id=uid//此批次的uid。active=true this。脏=这个。懒惰//对于懒惰的观察者来说。deps=[]这个。newdeps=[]这个。depds=new设置()这个。newdepds=new Set()this。表达式=进程。ENV。node _ ENV!=="生产"?rfn博览会。tostring(): ' ' if(Expo rfn的类型==' function '){ this。getter=Expo rfn } else { this。getter=parsePath(Expo rfn)if(!这个。getter){这个。getter=function(){ }进程。ENV。node _ ENV!=='production' warn('未能监视路径: '${expOrFn} ' ` '观察器只接受简单的点分隔路径若要完全控制,请改用函数.vm ) } } this.value=this.lazy?undefined : this.get()}参数中虚拟机表示组件实例,expOrFn表示要订阅的数据字段(字符串表示,例如a.b.c)或是一个要执行的函数,cb表示看守人运行后的回调函数,选项是选项对象,包含深度、用户、懒惰等配置。

看守人实例上有这些方法:

get:将副目标设置为当前看守人实例,在内部调用这个。吸气剂,如果此时某个被观察者观察的数据对象被取值了,那么当前看守人实例将会自动订阅数据对象的Dep实例addDep:接收参数副主任(副)实例),让当前看守人订阅dep cleanupDeps:清除新闻描述和新部门上记录的对dep的订阅信息更新:立刻运行看守人或者将看守人加入队列中等待统一冲洗管路:运行观察者,调用this.get()求值,然后触发回调评估:调用this.get()求值depend:遍历这个。德普斯,让当前看守人实例订阅所有dep拆卸:去除当前看守人实例所有的订阅数组方法

在src/core/observer/array.js中,Vue框架对数组的推送、弹出、移位、卸载、分拣、拼接、反转方法进行了改造,在调用数组的这些方法时,自动触发dep.notify(),解决了调用这些函数改变数组后无法触发更新的问题。

在某视频剪辑软件的官方文档中对这个也有说明:http://cn。vuejs。org/v2/guide/list。html #变异方法

总结

以上就是这篇文中的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

版权声明:Vue.js原理分析观察器模块详解是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。