手机版

Vue 2.0侦听器看属性代码详解

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

用法

-

先来看看官网的介绍:

官网介绍的很好理解了,也就是监听一个数据的变化,当该数据变化时执行我们的看方法看着选项是一个对象,键为需要观察的表达式(函数),还可以是一个对象,可以包含如下几个属性:

处理程序;对应的函数;可以带两个参数,分别是新的值和旧的值,上下文为当前某视频剪辑软件实例立即;侦听开始之后是否立即调用;默认为假同步;波尔值,是否同步执行,默认假的;如果设置了这个属性,当数据有变化时就会立即执行了,否则放到下一个滴答声中排队执行

例如:

!DOCTYPE html html lang=' en ' head meta charset=' UTF-8 '脚本src=' http :https://cdn。bootcss。com/vue/2。5 .16/vue。js '/脚本标题文档/标题/标题正文div id=' app ' p { { message } }/p button @ click=' test '测试/button /div脚本var app=new Vue({ el:'#app ',data : { message : ' hello world!},watch : { message : function(new val,val){ console.log(newval,val) },methods : { test :()=app。留言='你好Vue!} })/脚本/正文/htmlDOM渲染如下:

点击测试按钮后数字正射影像图变成了:

同时控制台输出:你好Vue!你好世界!

源码分析

-

某视频剪辑软件实例后会先执行_init()进行初始化(4579行)时,会执行initState()进行初始化,如下:

函数initState (vm) { //第3303行虚拟机_ watchers=[];var opts=vm .$ option SIF(opts . props){ initProps(VM,opts。道具);} if(opts。方法){ init方法(VM,opts。方法);} if(opts。数据){ init数据(VM);} else { observe(vm ._data={},true/* asRootData */);} if(opts。计算的){初始化计算的(VM,opts。计算的);} if (opts.watch opts.watch!==nativeWatch) { //如果传入了看且看不等于nativeWatch(细节处理,在火狐浏览器浏览器下目标的原型上含有一个看函数)initWatch(vm,opts。观看);//调用initWatch()函数初始化观看{ }函数initWatch (vm,watch) { //第3541行用于(手表中的定义变量键){ //遍历看里的每个元素var handler=watch[key];if(数组。isarray(handler)){ for(var I=0;I handler . lengthi){ createWatcher(VM,key,handler[I]);} } else { createWatcher(vm,键,处理程序);//调用createWatcher } } }函数createWatcher (//创建用户观察程序vm,expOrFn,处理程序,选项){ if(isplayanoobject(处理程序)){ //如果处理者是个对象,则将该对象的汉勒属性保存到处理者里面从这里看到值可以是个对象options=handler handler=handler . handler } if(类型为handler==' string '){ handler=VM[handler];}返回虚拟机$watch(expOrFn,处理程序,选项)//最后创建一个用户观看}Vue原型上的$手表构造函数如下:

vue。原型。$ watch=函数(//第3596行expOrFn,//监听的属性,例如例子里的消息cb,//对应的函数选项/选项){ var VM=this if(isplayanoobject(cb)){ return createWatcher(VM,expOrFn,CB,options)} options=options | | { };options.user=true//设置选项。用户为没错,表示这是一个用户观察var观察者=新观察器(vm、expOrFn、cb、options);//创建一个看守人对象if (options.immediate) { //如果有马上选项,则直接运行cb.call(vm,watcher。值);}返回函数Unwatchfn(){ watcher。拆掉();} };}侦听器对应的用户看的用户选项是真实的的,全局看守人如下:

var Watcher=函数观察者(//第3082行vm,expOrFn,//侦听的属性:消息cb,//对应的函数选项,IsRenderWatcher){ this。VM=VMif (isRenderWatcher) { vm ._观察者=这个;} vm ._watchers.push(这个);//选项if(options){ this。deep=!options.deepthis.user=!options.user//用户看这里的用户属性为没错,懒惰=!选项。懒惰;this.sync=!options.sync} else { this。深度=这个。用户=这个。懒惰=这个。sync=false} this.cb=cbthis。id=uid $ 1;//用于批处理这是主动的。的=truethis.dirty=this。懒惰;//对于懒惰的观察者来说,这个。deps=[];这个。NewDeps=[];这个。desi des=new _ Set();这个。new depds=new _ Set();这个。表达式=exporfn。ToString();//分析吸气if的表达式(exporff==' function ')的类型为{ this。getter=exporff} else { //侦听器执行到这里,这个。getter=parsePath(expOrFn);//获取对应的是parsePath()返回的匿名函数if(!这个。getter){这个。getter=function(){ };发展!=='production' warn('未能监视路径路径path: \ ' ' expOrFn ' ' ' '监视程序只接受简单的点分隔路径'若要完全控制,请改用函数. VM);} } this.value=this.lazy?未定义的:这个。get();//最后会执行get()方法};函数parsePath(路径){ //解析路劲若(拜若。测试(路径)){ return } var segments=path。拆分(' . ');返回函数{ //返回一个函数,参数是一个对象for(var I=0;长度;i ) { if(!obj){ return } obj=obj[segments[I]];}返回obj }}执行看守人的get()方法时就将监听的元素也就是例子里的消息对应的依赖的列表将当前观察者(用户观察者)作为订阅者,如下:

观察者。原型。get=函数get(){//第3135行pushTarget(这个);//将当前用户看保存到副目标总=中定义变量值;var vm=this.vm尝试{ value=this.getter.call(vm,VM);//执行用户瓦特谢尔的getter()方法,此方法会将当前用户看守人作为订阅者订阅起来抓住这个。用户){ handleError(e,vm,(' watcher的getter ')(这。表达式)' \ ' '));} else { throw e } }最后{ //'触摸'每个属性,以便它们都被跟踪为//依赖,用于深度监视如果(这个。deep){ traverse(值);} popTArGet();//恢复之前的观察这个。clean updeps();}返回值};当我们点击按钮了修改了app.message时就会执行app.message对应的访问控制器的设置()方法,就会执行这个用户看守人的更新()方法,如下:

watcher . prototype . update=function update(){//第3200行更新watcher/*伊斯坦布尔ignore else */if(this。懒){这个。dirty=true} else if (this.sync) {//如果$this.sync为true,则直接运行this.run获取结果this . run();} else { queueWatcher(this);//否则,调用queueWatcher()函数,将所有待更新的观察器()推入队列} };观察者。原型。run=function run(){//第3215行将调用get()来获取相应的值if (this。有效){var值=这个。get();if(值!==this.value || //即使//值相同,Deep watchers和Object/Arrays上的watchers也应该激发,因为该值可能//已经发生了变化。isObject(value) || this.deep ) { //设置新值var oldValue=this.valuethis.value=value如果(this.user) {//如果是用户,看着试试{this。cb。叫(这个。虚拟机、价值、旧价值);//执行此回调函数vm作为上下文参数1,它是新值,参数2是旧值,即函数(newval,val) {console.log (newval,val)} function } catch(e){ handleerror(e,this.vm,(' callback for watcher \ ')(this。表达式)' \ \。} } else { this.cb.call(this.vm,value,old value);} } }};对于听众来说,Vue的内部过程是这样的

摘要

以上是边肖介绍的Vue 2.0监听手表属性代码的详细说明。希望对大家有帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!如果你觉得这篇文章对你有帮助,请转载,请注明出处,谢谢!

版权声明:Vue 2.0侦听器看属性代码详解是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。