当前位置: 首页 > Web前端 > HTML

vue源码学习-响应式原理

时间:2023-03-27 23:40:40 HTML

杩欑瘒鏂囩珷涓昏鏄兂璁板綍涓嬭嚜宸卞湪瀛︿範vue涓搷搴斿紡鍘熺悊鏃堕亣鍒扮殑涓€浜涢棶棰樸€傚鏈夐敊璇紝璇锋寚姝o紒1銆乄atcher銆丏ep銆丱bserver璐熻矗浠€涔堬紵Observer璐熻矗閫掑綊鏁版嵁鍜屾墍鏈夊瓙鏁版嵁锛岄€氳繃Object.defineProperty涓哄睘鎬у畾涔塯etter/setter锛岀洃鍚暟鎹彉鍖栵紝瀹氫箟鏁版嵁涓哄搷搴斿紡銆備絾鏄粎浠呭皝瑁匫bject.defineProperty锛岀洃鍚暟鎹彉鍖栨槸娌℃湁鏁堟灉鐨勩€備富瑕佺洰鐨勬槸鏀堕泦渚濊禆鍏崇郴銆侽bject.defineProperty(obj,key,{enumerable:true,configurable:true,get:functionreactiveGetter(){varvalue=getter?getter.call(obj):val;/*鐪佺暐*/if(Dep.target){//鏀堕泦渚濊禆dep.depend();}杩斿洖鍊紏,set:functionreactiveSetter(newVal){/*鐪佺暐*/dep.notify();//瑙﹀彂渚濊禆}});//涓€鑸儏鍐典笅锛孋ollectdependenciesin`getter`鍜宍setter`涓殑瑙﹀彂鍣ㄤ緷璧栭」銆傛敹闆嗕緷璧栧叧绯荤殑鍘熷洜鏄綋鏁版嵁灞炴€у彂鐢熷彉鍖栨椂閫氱煡鏁版嵁浣跨敤鐨勫湴鏂广€傚湪鍝噷鏀堕泦渚濊禆椤癸紵Dep涓敹闆嗕緷璧栵紝Dep鐢ㄤ簬鏀堕泦渚濊禆銆佸垹闄や緷璧栥€侀€氱煡渚濊禆銆傞偅涔堝畠渚濊禆浜庤皝鍛紵渚濊禆鏄瀵熻€呫€傘€婃繁鍏ユ祬鍑簐ue.js銆嬪緢濂界殑瑙i噴浜嗕负浠€涔堣鎶婁緷璧栧皝瑁呭埌涓€涓猈atcher绫讳腑锛氬綋涓€涓睘鎬ф敼鍙樼殑鏃跺€欙紝鎴戜滑闇€瑕侀€氱煡鏁版嵁琚娇鐢ㄧ殑鍦版柟锛岃€屾暟鎹浣跨敤鐨勫湴鏂规湁寰堝锛岃€岀被鍨嬩笉鍚屻€傚畠鍙兘鏄竴涓ā鏉匡紝涔熷彲鑳芥槸鐢ㄦ埛缂栧啓鐨勬墜琛ㄣ€傝繖鏃跺€欏氨闇€瑕佹娊璞″嚭涓€涓被鏉ラ泦涓鐞嗚繖浜涙儏鍐点€傜劧鍚庯紝鎴戜滑鍦ㄤ緷璧栨敹闆嗛樁娈靛彧鏀堕泦杩欎釜灏佽绫荤殑瀹炰緥锛屽彧閫氱煡涓€娆°€傜劧鍚庯紝瀹冭礋璐i€氱煡鍏朵粬鍦版柟銆?銆丏ep鍜學atcher鐨勫叧绯伙紵鍒氬紑濮嬪涔燰ue婧愮爜鐨勬椂鍊欙紝鎴戜篃寰堝洶鎯戣繖閲岋細Dep.target鏄仛浠€涔堢殑锛焏ep.target鍏跺疄灏辨槸褰撳墠鐨刉atcher瀹炰緥锛屾槸涓€涓叏灞€鍞竴鐨勯潤鎬佸彉閲忋€傝鍙栨暟鎹椂锛屼細瑙﹀彂杩欐潯鏁版嵁鐨刧etter锛岃Е鍙慻etter鏃朵細鎵цif(Dep.target){dep.depend();}鍦ㄨ嚜宸辨敹闆嗘暟鎹殑Dep涓紝涓€鑸唬鐮佹槸濡備笅锛歡et(){/*灏嗚嚜宸辩殑watcher瑙傚療鑰呭疄渚嬭缃负Dep.target渚濊禆闆嗗悎銆?/pushTarget(this)letvalueconstvm=this.vmvalue=this.getter.call(vm,vm)/*灏嗚瀵熻€呭疄渚嬩粠鐩爣鏍堜腑鍙栧嚭骞舵竻绌篋ep.target*/popTarget()杩斿洖鍊紏/*璁剧疆watcher瑙傚療鑰呭疄渚嬩负Dep.target锛岀敤浜庝緷璧栨敹闆嗐€傚悓鏃跺皢瀹炰緥瀛樺叆鐩爣鏍?/functionpushTarget(_target:Watcher){if(Dep.target)targetStack.push(Dep.target)Dep.target=_target}涓轰粈涔圖ep浣跨敤addDep鏂规硶鏀堕泦渚濊禆鍦╓atcher涓紝骞舵湁涓€涓猟eps鏁扮粍璁板綍Watcher涓殑dep锛熶负浜嗗洖绛旇繖涓棶棰橈紝鎴戜滑涓句釜渚嬪瓙馃尠锛屾垜浠湅涓€涓媀ue涓殑vm.$watch锛孷ue.prototype.$watch=function(expOrFn:string|Function,cb:Function,options?:Object):Function{constwatcher=newWatcher(vm,expOrFn,cb,options)/*鐪佺暐*/returnfunctionunwatchFn(){/*浠庢墍鏈変緷璧栭泦鍚堣闃呭垪琛ㄤ腑绉婚櫎鑷韩*/watcher.teardown()}}}/*Watcher鐨勯€氱敤浠g爜/teardown濡備笅*//*浠庢墍鏈変緷璧栭泦鍚堣闃呭垪琛ㄤ腑绉婚櫎鑷韩*/functionteardown(){leti=this.deps.lengthwhile(i--){this.deps[i].removeSub(this)}this.active=false}璇ユ柟娉曡繑鍥炰竴涓彇娑堣瀵熸暟鎹殑unwatchFn鏂规硶锛屾湰璐ㄤ笂鏄粠褰撳墠瑙傚療鏁版嵁鐨勪緷璧栧垪琛ㄤ腑绉婚櫎Watcher瀹炰緥銆傚鏋滃湪getter涓€氳繃渚濊禆鏀堕泦锛屽彧鍦ㄦ暟鎹殑Dep锛堜緷璧栧垪琛級涓褰曚簡Watcher锛岄偅涔堝湪Dep涓彧鐭ラ亾鍝簺Watcher鍦ㄧ洃鍚暟鎹紝鑰屽湪Watcher涓紝骞朵笉鐭ラ亾鏄皝浠栦滑宸茬粡璁㈤槄浜嗐€傦紙Watcher瀹炰緥鏀惰繘浜嗗摢涓狣ep锛燂級锛屾垜涓嶇煡閬撹嚜宸辫闃呬簡璋侊紝閭d箞閫氱煡璋佸彇娑堣瀵熷憿锛熸墍浠ユ垜浠渶瑕佸湪Dep鍜學atcher涓簰鐩歌褰曪紝褰㈡垚澶氬澶氱殑鍏崇郴銆傛墍浠ユ垜浠娇鐢―ep.target.addDep(this)functionaddDep(dep:Dep){constid=dep.idif(!this.newDepIds.has(id)){this.newDepIds.add(id)this.newDeps.push(dep)if(!this.depIds.has(id)){dep.addSub(this)}}}閫氳繃璁板綍newDepIds鍜宯ewDeps锛屽湪Watcher涓褰曟敹闆嗕簡鍝簺Dep锛屾渶鍚庤褰曡嚜宸遍€氳繃dep.addSub(this)鍦―ep涓紝鏄笉鏄緢宸у锛?.__ob__鐨勪綔鐢ㄦ槸浠€涔堬紵Dep瀵筄bserver瀹炰緥鏈変粈涔堜綔鐢紵棣栧厛锛孫bserver瀹炰緥淇濆瓨鍦╛_ob__灞炴€т笂銆俖_ob__鐨勭涓€涓綔鐢ㄦ槸鏍囪褰撳墠鍊兼槸鍚﹀凡缁忚Observer杞寲涓哄搷搴斿紡鏁版嵁锛岄伩鍏嶅悗缁噸澶嶆搷浣溿€傚叾娆★紝Vue瀵筄bject鐨勫彉鍖栨娴嬶紝鏀堕泦渚濊禆锛岃Е鍙戜緷璧栵紝鍙互鍦ㄤ竴涓棴鍖呬腑璁块棶dep瀹炰緥銆俧unctiondefineReactive(){/*鍦ㄩ棴鍖呬腑瀹氫箟涓€涓猟ep瀵硅薄*/constdep=newDep()Object.defineProperty(obj,key,{get:functionreactiveGetter(){/*鍋氫緷璧栨敹闆?/dep.depend()},set:functionreactiveSetter(newVal){/*dep瀵硅薄閫氱煡鎵€鏈夎瀵熻€?/dep.notify()}})}浣嗘槸瀵逛簬Array锛屼緷璧栨槸鏀堕泦鍦╣etters涓紝渚濊禆鏄湪鎷︽埅鍣ㄤ笂瑙﹀彂鐨勶紝涓嶇啛鎮夌殑浜哄畠锛岃鑷鏌ョ湅Vue澶勭悊鏁扮粍鐨勪唬鐮併€備竴鑸唬鐮佸涓嬶細['push','pop','shift','unshift','splice','sort','reverse'].forEach(function(method){constoriginal=arrayProto[method]def(arrayMethods,method,functionmutator(){/*鏁扮粍涓柊鎻掑叆鐨勫厓绱犻渶瑕侀噸鏂拌瀵熸墠鑳藉搷搴?/constob=this.__ob__/*dep閫氱煡鎵€鏈夋敞鍐岀殑瑙傚療鑰呰繘琛屽搷搴斿鐞?/ob.dep.notify()returnresult})})鎴戜滑鍙互鐪嬪埌鍦ㄦ嫤鎴櫒涓紝骞舵病鏈塪ep瀹炰緥鍙緵鎴戜滑璁块棶锛屼絾鏄敱浜庢嫤鎴櫒鏄prototype杩欑灏佽锛屾墍浠ュ彲浠ヨ闂埌褰撳墠杩愯鐨勬暟缁?this)鍦ㄦ嫤鎴櫒涓紝鎵€浠ラ渶瑕佺粰姣忎釜妫€娴嬪埌鐨勬暟鎹缃甠_ob__灞炴€э紝杩欓噷鍙互閫氳繃this.__ob__.dep瀹炰緥鑾峰彇dep銆傛渶鍚庢兂璇寸殑鏄紝瀛︿範婧愮爜鏄负浜嗘洿鐔熺粌鍦颁娇鐢╒ue妗嗘灦寮€鍙戯紝浣嗘洿閲嶈鐨勬槸鐞嗚В妗嗘灦涓轰粈涔堣杩欐牱璁捐锛屽苟灏嗗叾搴旂敤鍒颁互鍚庣殑鏃ュ父寮€鍙戜腑锛屼互鏇村ソ鐨勬彁楂樹綘鑷繁锛佹渶鍚庯紝鎴戞槸鍓嶇鏂颁汉鍛ㄦ檽闃炽€傛垜鍐欐枃绔犺褰曡嚜宸卞湪鏃ュ父宸ヤ綔涓亣鍒扮殑闂鍜屾墍瀛﹀埌鐨勪笢瑗匡紝浠ユ鏉ユ彁楂樿嚜宸便€傚鏋滄偍瑙夊緱鏈枃瀵规偍鏈夌敤锛岃鐐逛釜璧為紦鍔变竴涓嬪惂~

最新推荐
猜你喜欢