当前位置: 首页 > Web前端 > vue.js

Vue3.0中Proxy

时间:2023-03-31 17:55:11 vue.js

鐩綍鐨勭畝鍗曢€氫織鐞嗚ВProxyVue2.0浣跨敤Object.defineProperty()瀹炵幇鏁版嵁鍝嶅簲Vue3.0鍏朵粬搴旂敤浣跨敤ProxyProxy浠€涔堟槸浠g悊锛熷彲浠ョ悊瑙d负鍦ㄥ璞″墠璁剧疆涓€涓€滄埅璺濃€濄€傝闂璞℃椂锛屽繀椤荤粡杩囪繖涓€灞傛嫤鎴€傛剰鍛崇潃浣犲彲浠ュ湪杩欎竴灞傛嫤鎴腑杩涜鍚勭鎿嶄綔銆傛瘮濡備綘鍙互鍦ㄨ繖涓€灞傛嫤鎴鐞嗗師濮嬪璞★紝杩斿洖浣犳兂瑕佽繑鍥炵殑鏁版嵁缁撴瀯銆侲S6鍘熺敓鎻愪緵浜哖roxy鏋勯€犲嚱鏁般€侻DN涓婄殑瑙i噴鏄細浠g悊瀵硅薄鐢ㄤ簬瀹氫箟鍩烘湰鎿嶄綔锛堝灞炴€ф煡鎵俱€佽祴鍊笺€佹灇涓俱€佸嚱鏁拌皟鐢ㄧ瓑锛夌殑鑷畾涔夎涓恒€傝鎴戜滑鍏堢湅鐪嬪浣曚娇鐢ㄥ畠銆俢onstp=newProxy(target,handler);target锛氳鎷︽埅鐨勭洰鏍囧璞★紙鍙互鏄换浣曠被鍨嬬殑瀵硅薄锛屽寘鎷師鐢熸暟缁勩€佸嚱鏁帮紝鐢氳嚦鏄彟涓€涓唬鐞嗭級handler锛氬畾涔夎鎷︽埅鐨勮涓虹殑瀵硅薄constp=newProxy({},{get(target,propKey){return'鍝堝搱锛屼綘琚垜灞忚斀浜?;}});console.log(p.name);//鍝堝搱锛屼綘琚垜灞忚斀浜嗘敞鎰忥紝Proxy鏄敤鏉ユ搷浣滃璞$殑銆備唬鐞嗙殑鐩殑鏄墿灞曞璞$殑鑳藉姏銆傚啀鐪嬩竴涓緥瀛愶紝鎴戜滑鍙互瀹炵幇涓€涓姛鑳斤細瀵硅薄鐨刵ame灞炴€т笉鍏佽琚閮ㄤ慨鏀广€俢onstp=newProxy({},{set(target,propKey,value){if(propKey==='name'){thrownewTypeError('name灞炴€т笉鍏佽淇敼');}//notaname灞炴€э紝鐩存帴淇濆瓨target[propKey]=value;}});p.name='proxy';//TypeError:name灞炴€т笉鍏佽淇敼p.a=111;console.log(p.a);//111babel鏄敤鏉ヨ浆鎹㈣娉曠殑锛屽儚鏂扮殑API锛堟瘮濡侫rray.from,Array.prototype.includes锛夛紝鎴戜滑闇€瑕佸畨瑁呴澶栫殑鍖呮潵鏀寔锛屾瘮濡俒core-js/stable]()鍜孾regenerator-runtime/runtime]()锛圥S锛歜abel7.x鍚庝笉鎺ㄨ崘浣跨敤@babel/polyfill锛夛紝鐒跺悗杩樻湁涓€浜汚PI锛圫tring#normalize銆丳roxy銆乫etch绛夛級core-js涓嶆彁渚沺olyfill鏆傛椂鍙互鍙傝€冨畼鏂规枃妗ore-js#missing-polyfills銆侾roxy涓€鍏辨敮鎸?3绉嶆嫤鎴搷浣滐紝鍏蜂綋鍙互鏌ョ湅MDN銆倂ue2.x鏄浣曞疄鐜版暟鎹搷搴旂殑锛熼€掑綊閬嶅巻data涓殑鏁版嵁锛屼娇鐢∣bject.defineProperty()鍔寔getter鍜宻etter锛屽湪getter涓仛鏁版嵁渚濊禆鐨勯泦鍚堝鐞嗭紝鍦╯etter涓洃鍚暟鎹彉鍖栵紝閫氱煡subscription褰撳墠鏁版嵁鍦ㄥ摢閲屻€傞儴鍒嗘簮鐮乻rc/core/observer/index.js#L156-L193锛岀増鏈负2.6.11濡備笅letchildOb=!shallow&&observe(val)//瀵筪ata涓殑鏁版嵁杩涜娣卞害閬嶅巻锛屽苟娣诲姞瀵硅薄鐨勬瘡涓睘鎬eactiveObject.defineProperty(obj,key,{enumerable:true,configurable:true,get:functionreactiveGetter(){constvalue=getter?getter.call(obj):valif(Dep.target){//寤虹珛渚濊禆闆嗗悎dep.depend()if(childOb){childOb.dep.depend()if(Array.isArray(value)){//濡傛灉鏄暟缁勶紝闇€瑕佷负姣忎釜鎴愬憳鏀堕泦渚濊禆銆傚鏋滄暟缁勭殑鎴愬憳浠嶇劧鏄暟缁勶紝鍒欓€掑綊銆俤ependArray(value)}}}杩斿洖鍊紏,set:functionreactiveSetter(newVal){constvalue=getter?getter.call(obj):val/*eslint-disableno-self-compare*/if(newVal===value||(newVal!==newVal&&value!==value)){return}/*eslint-澶嶅埗浠g爜鍚敤鏃犺嚜鎴戞瘮杈?/if(process.env.NODE_ENV!=='production'&&customSetter){customSetter()}if(getter&&!setter)returnif(setter){setter.call(obj,newVal)}else{val=newVal}//闇€瑕佸啀娆¤瀵熸柊鍊硷紝淇濊瘉鏁版嵁鍝嶅簲childOb=!shallow&&observe(newVal)//閫氱煡鎵€鏈夎瀵熻€呮暟鎹彉鍖杁ep.notify()}})鍋氶敊浜嗕粈涔堣繖锛熸棤娉曟娴嬪埌瀵硅薄灞炴€х殑澧炲垹鏀规煡锛氬綋浣犵粰瀵硅薄娣诲姞涓€涓柊鐨勫睘鎬ewProperty鏃讹紝褰撳墠鏂版坊鍔犵殑灞炴€у苟娌℃湁娣诲姞Vue妫€娴嬫暟鎹洿鏂扮殑鏈哄埗锛堝洜涓烘槸鍦ㄥ垵濮嬪寲涔嬪悗娣诲姞鐨勶級銆倂ue.$set璁¬ue鐭ラ亾浣犳坊鍔犱簡涓€涓睘鎬э紝瀹冧細涓轰綘澶勭悊銆?set涔熼€氳繃璋冪敤Object.defineProperty()杩涜澶勭悊銆傛棤娉曠洃鍚埌鏁扮粍涓嬫爣鐨勫彉鍖栵紝瀵艰嚧鐩存帴灏嗘暟缁勪笅鏍囩殑璁剧疆鍊间紶缁欎竴涓暟缁勬棤娉曞疄鏃跺搷搴斻€傚綋data閲岄潰鐨勬暟鎹緢澶氾紝灞傛寰堟繁鐨勬椂鍊欙紝灏变細鍑虹幇鎬ц兘闂锛屽洜涓篸ata閲岄潰鐨勬墍鏈夋暟鎹兘瑕侀亶鍘嗕竴閬嶏紝璁剧疆涓哄搷搴斿紡銆俈ue3.0浣跨敤Proxyvue3.0杩樻病鏈夋寮忓彂甯冿紝浣嗘槸vue-next鐨勭浉鍏充唬鐮佸凡缁忓紑婧愶紝鐩墠鏄疉lpha鐗堟湰銆備负浠€涔堣浣跨敤Proxy鏉ヨВ鍐充互涓婇棶棰樺憿锛熶富瑕佹槸鍥犱负Proxy鏄竴涓嫤鎴璞★紝濡傛灉涓€涓璞¤鈥滄嫤鎴€濓紝閭d箞澶栭儴瀵硅瀵硅薄鐨勪换浣曡闂兘蹇呴』鍏堢粡杩囪繖涓€灞傛嫤鎴€備笉绠¤闂璞$殑浠€涔堝睘鎬э紝涓嶇鏄箣鍓嶅畾涔夌殑杩樻槸鏂板鐨勶紝閮戒細鍘绘嫤鎴€傚浜庝竴涓畝鍗曠殑馃尠锛屼竴涓畝鍗曠殑鏁版嵁鍝嶅簲鏄娇鐢∣bject.defineProperty()鍜孭roxy鍒嗗埆浣跨敤Object.defineProperty()瀹炵幇鐨勶細classObserver{constructor(data){//閬嶅巻鍙傛暟data鐨勫睘鎬э紝骞舵坊鍔犲埌thisfor(letkeyofObject.keys(data)){if(typeofdata[key]==='object'){data[key]=newObserver(data[key]);}Object.defineProperty(this,key,{enumerable:true,configurable:true,get(){console.log('Youvisited'+key);returndata[key];//鏂规嫭鍙锋柟娉曞彲浠ヤ娇鐢ㄥ彉閲忎綔涓哄睘鎬у悕绉帮紝浣嗙偣鏂规硶涓嶈兘锛泒,set(newVal){console.log('Youset'+key);console.log('new'+key+'='+newVal);if(newVal===data[key]){return;}data[key]=newVal;}})}}}constobj={name:'app',age:'18',a:{b:1,c:2,},}constapp=newObserver(obj);app.age=20;console.log(app.age);app.newPropKey='鏂板睘鎬?;console.log(app.newPropKey);涓婇潰浠g爜鐨勬墽琛岀粨鏋滄槸//淇敼obj鐨勫師灞炴€ge鐨勮緭鍑轰綘璁剧疆agenewage=20浣犺闂產ge20//璁剧疆鏂板睘鎬х殑杈撳嚭鏂板睘鎬у彲浠ュ彲浠ョ湅鍑猴紝娣诲姞涓€涓璞$殑灞炴€т笉鍙楀唴閮ㄧ洃鎺с€傛柊娣诲姞鐨勫睘鎬ч渶瑕佸啀娆′娇鐢∣bject.defineProperty()鎵嬪姩鐩戞帶銆傝繖灏辨槸涓轰粈涔堝湪vue2.x涓棤娉曟娴嬪埌瀵硅薄灞炴€х殑澧炲垹鏀规煡锛屽唴閮ㄦ彁渚涚殑$set鏄€氳繃璋冪敤Object.defineProperty()鏉ュ鐞嗙殑銆備笅闈㈡垜浠娇鐢≒roxy浠f浛Object.defineProperty()鏉ュ疄鐜癱onstobj={name:'app',age:'18',a:{b:1,c:2,},}constp=newProxy(obj,{get(target,propKey,receiver){console.log('Youvisited'+propKey);returnReflect.get(target,propKey,receiver);},set(target,propKey,value,receiver){鎺у埗鍙般€俵og('youset'+propKey);console.log('new'+propKey+'='+value);Reflect.set(target,propKey,value,receiver);}});p.age='20';console.log(p.age);p.newPropKey='鏂板睘鎬?;console.log(p.newPropKey);鍙互鐪嬪埌濡備笅杈撳嚭//淇敼鍘熷璞$殑age灞炴€э紝灏哸ge璁剧疆涓烘柊鐨刟ge=20Youhavevisitedage20//SettingnewpropertiesYouhavesetnewPropKeynewnewPropKey=Newproperties浣犺闂簡newPropKey鏂板睘鎬у彲浠ョ湅鍒版柊娣诲姞鐨勫睘鎬т笉闇€瑕侀噸鏂版坊鍔犲搷搴斿紡澶勭悊锛屽洜涓篜roxy鏄瀵硅薄鐨勬搷浣滐紝鍙璁块棶瀵硅薄锛屽氨浼氳蛋Proxy鐨勯€昏緫銆俁eflect锛堝湪ES6涓紩鍏ワ級鏄竴涓唴缃璞★紝鎻愪緵鎷︽埅JavaScript鎿嶄綔鐨勬柟娉曘€傚皢Object瀵硅薄鐨勪竴浜涙槑鏄惧睘浜庤瑷€鍐呴儴鐨勬柟娉曪紙渚嬪Object.defineProperty()锛夋斁鍦≧eflect瀵硅薄涓娿€備慨鏀逛竴浜汷bject鏂规硶鐨勮繑鍥炵粨鏋滐紝浣垮叾鏇村悎鐞嗐€傝瀵硅薄鎿嶄綔鎴愪负鍔熻兘琛屼负銆傚叿浣撳唴瀹硅MDNProxy鐨勫叾浠栧簲鐢ㄣ€傞櫎浜嗗嵆灏嗗彂甯冪殑vue3.0锛岃繕鏈夊摢浜涘簱浣跨敤浜哖roxy锛焏objs/dob鏄敤浠g悊閲嶅啓mobx鐨勮В鍐虫柟妗堛€俰mmer瀹炵幇涓嶅彲鍙樻暟鎹被鍨嬨€侷mmer鐨勫仛娉曟槸鍐呴儴缁存姢涓€涓姸鎬侊紝鍔寔鎵€鏈夋搷浣滐紝鍐呴儴鍒ゆ柇鏄惁鏈夊彉鍖栵紝鏈€鍚庡喅瀹氬浣曡繑鍥炪€傚叿浣撳彲浠ュ弬鑰冭繖绡囨枃绔爉mer.js绠€浠嬪強婧愮爜娴呮瀽銆傚畠浠兘鏄敤鏉ユ嫤鎴璞$殑璇诲啓锛屽湪璇诲啓涓仛涓€浜涢澶栫殑鍒ゆ柇鍜屾搷浣溿€傛€荤粨Proxy鐢ㄤ簬鎿嶄綔瀵硅薄锛屾墿灞曞璞$殑鑳藉姏銆侽bject.defineProperty()瀵瑰璞″睘鎬ц繘琛屾搷浣溿€俈ue2.x浣跨敤Object.defineProperty()鏉ュ疄鐜版暟鎹搷搴旓紝浣嗘槸鐢变簬Object.defineProperty()鏄瀵硅薄灞炴€х殑鎿嶄綔锛屾墍浠ラ渶瑕佸瀵硅薄杩涜娣卞害閬嶅巻鎵嶈兘瀵瑰睘鎬ц繘琛屾搷浣溿€俈ue3.0浣跨敤Proxy鎷︽埅瀵硅薄銆傛棤璁哄瀵硅薄杩涜浠€涔堟牱鐨勬搷浣滐紝閮戒細璧癙roxy鐨勫鐞嗛€昏緫銆俈ue3.0銆乨objs/dob銆乮mmer绛夊簱鐩墠閮芥槸浣跨敤Proxy璇诲彇瀵硅薄銆傜紪鍐欐嫤鎴苟鍋氫竴浜涢澶栫殑澶勭悊銆傚弬鑰冩繁鍏ュ搷搴斿紡鍘熺悊鍒楄〃娓叉煋ECMAScript6鍏ラ棬-ProxyMDN-proxy闈㈣瘯瀹橈細Proxy鍦ㄥ疄鐜板弻鍚戠粦瀹氭柟闈㈡瘮defineproperty濂藉湪鍝噷锛熶笉濂芥剰鎬濓紝瀛︿範Proxy鐪熺殑鍙互涓烘墍娆蹭负Immer.js浠嬬粛鍙婃簮鐮佸垎鏋?/p>