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

终于彻底理解了Watch和WatchEffect,原来功能这么强大!

时间:2023-04-01 12:10:52 vue.js

浠ュ墠浠ヤ负鍙互鐢╳atch鍜寃atchEffect锛屽悗鏉ュ彂鐜板彧鏄矖娴呯殑浜嗚В銆傛渶杩戞暣鐞嗕簡Vue3鐨勭洃鍚櫒锛屽垎浜粰澶у銆傜湅鐪嬫湁娌℃湁浠€涔堜笉鎳傜殑锛屼竴璧锋潵瀛︿範鍚э紒Watch鐨勫熀鏈敤娉曞綋鎴戜滑闇€瑕佸湪鏁版嵁鍙樺寲鏃舵墽琛屼竴浜涒€滃壇浣滅敤鈥濓細姣斿鏇存敼DOM鍜屾墽琛屽紓姝ユ搷浣滄椂锛屾垜浠彲浠ヤ娇鐢╳atch鍑芥暟锛?scriptsetup>import{ref,watch}from'vue'constquestion=ref('')constanswer=ref('Thisisanswer.;-)')//鍚竴涓猺efwatch(question,async(newQuestion,oldQuestion)=>{answer.value='Thinking...'constres=awaitfetch('https://...')answer.value=(awaitres.json()).answer})watch()涓€鍏卞彲浠ユ帴鍙椾笁涓弬鏁帮紝鐩戝惉鏁版嵁婧愩€佸洖璋冨嚱鏁板拰閰嶇疆閫夐」銆俵istenerdatasourcewatch鐨勭涓€涓弬鏁板彲浠ユ槸涓嶅悓褰㈠紡鐨勨€滄暟鎹簮鈥濓紝鍙互鏄細涓€涓猺ef锛屼竴涓猚omputedproperty锛屼竴涓猤etter鍑芥暟锛堜竴涓湁杩斿洖鍊肩殑鍑芥暟锛夛紝涓€涓暟缁勭殑鍊间互涓婄被鍨嬬殑鍝嶅簲瀵硅薄constx=ref(1)consty=ref(1)constdoubleX=computed(()=>x.value*2)constobj=reactive({count:0})//singlerefwatch(x,(newValue)=>{console.log(`xis${newValue}`)})//璁$畻灞炴€atch(doubleX,(newValue)=>{console.log(`doubleXis${newValue}`)})//getterFunctionwatch(()=>x.value+y.value,(sum)=>{console.log(`sumofx+yis:${sum}`)})//鍝嶅簲瀵硅薄watch(obj,(newValue,oldValue)=>{//褰撳祵濂楀睘鎬ф敼鍙樻椂瑙﹀彂//娉ㄦ剰锛氳繖閲岀殑`newValue`绛変簬`oldValue`//鍥犱负瀹冧滑鏄悓涓€涓璞★紒})//浠ヤ笂绫诲瀷鍊兼暟缁剋atch([x,()=>y.value],([newX,newY])=>{console.log(`xis${newX}andyis${newY}`)})娉ㄦ剰涓嶈兘鐩存帴鍚睘鎬鍙嶅簲瀵硅薄鐨勫€硷紝渚嬪锛歝onstobj=reactive({count:0})//閿欒锛屽洜涓簑atch()鑾峰彇鐨勫弬鏁版槸涓€涓暟瀛梬atch(obj.count,(count)=>{console.log(`countis:${count}`)})杩欓噷闇€瑕佷娇鐢ㄤ竴涓繑鍥炲睘鎬х殑getter鍑芥暟锛?/Provideagetterfunctionwatch(()=>obj.count,(count)=>{console.log锛坄璁℃暟鏄細${count}`)})鍥炶皟鍑芥暟watch鐨勭浜屼釜鍙傛暟鏄暟鎹彉鍖栨椂鎵ц鐨勫洖璋冨嚱鏁般€傛鍥炶皟鍑芥暟鎺ュ彈涓変釜鍙傛暟锛氭柊鍊笺€佹棫鍊煎拰鐢ㄤ簬娓呯悊鍓綔鐢ㄧ殑鍥炶皟鍑芥暟銆傝繖涓洖璋冨嚱鏁颁細鍦ㄤ笅娆℃墽琛宻ideeffect涔嬪墠璋冪敤锛屽彲浠ョ敤鏉ユ竻闄ゆ棤鏁堢殑sideeffect锛屾瘮濡傜瓑寰呭紓姝ヨ姹傦細constid=ref(1)constdata=ref(null)watch(id,async(newValue,oldValue,onCleanup)=>{const{response,cancel}=doAsyncWork(id.value)//褰揱id`鏀瑰彉鏃惰皟鐢╜cancel`//鍙栨秷涔嬪墠鏈畬鎴愮殑璇锋眰onCleanup(cancel)data.value=awaitresponse.json()})watch鐨勮繑鍥炲€兼槸涓€涓敤鏉ュ仠姝㈠壇浣滅敤鐨勫嚱鏁帮細constunwatch=watch(()=>{})//...unwatch()褰撶洃鍚櫒鏄笉鍐嶉渶瑕佹敞鎰忥細浣跨敤鍚屾璇彞鍒涘缓鐨勭洃鍚櫒浼氳嚜鍔ㄧ粦瀹氬埌瀹夸富缁勪欢瀹炰緥涓婏紝褰撳涓荤粍浠跺嵏杞芥椂浼氳嚜鍔ㄥ仠姝€備娇鐢ㄥ紓姝ュ洖璋冨垱寤轰睛鍚櫒涓嶄細缁戝畾鍒板綋鍓嶇粍浠讹紝鎮ㄥ繀椤绘墜鍔ㄥ仠姝㈠畠浠ラ槻姝㈠唴瀛樻硠婕忋€傚涓嬩緥锛?scriptsetup>import{watchEffect}from'vue'//缁勪欢鍗歌浇浼氳嚜鍔ㄥ仠姝atchEffect(()=>{})//缁勪欢鍗歌浇涓嶄細鍋滄锛乻etTimeout(()=>{watchEffect(()=>{})},100)閰嶇疆閫夐」watch鐨勭涓変釜鍙傛暟鏄彲閫夊璞★紝鏀寔浠ヤ笅閫夐」锛歩mmediate锛氬湪鐩戝惉鍣ㄤ腑鍒涘缓鍥炶皟鏄珛鍗宠Е鍙戙€俤eep锛氭繁搴﹂亶鍘嗭紝浠ヤ究鍦ㄨ繘琛屾繁灞傛洿鏀规椂瑙﹀彂鍥炶皟銆俧lush锛氬洖璋冨嚱鏁扮殑瑙﹀彂鏃舵満銆俻re锛氶粯璁わ紝dom鏇存柊鍓嶈皟鐢紝post锛歞om鏇存柊鍚庤皟鐢紝sync鍚屾璋冪敤銆俹nTrack/onTrigger锛氱敤浜庤皟璇曠殑鎸傞挬銆傚湪鏀堕泦渚濊禆椤瑰苟瑙﹀彂鍥炶皟鏃惰皟鐢ㄣ€俤eeplistener鐩存帴浼犲叆涓€涓猺eactive瀵硅薄缁檞atch()锛岄粯璁や細鍒涘缓涓€涓猟eeplistener鈥斺€旀墍鏈夊祵濂楃殑灞炴€у彉鍖栭兘浼氳瑙﹀彂锛歝onstobj=reactive({count:0})watch(obj,(newValue,oldValue)=>{//褰撳祵濂楀睘鎬ф敼鍙樻椂瑙﹀彂//娉ㄦ剰锛氳繖閲宍newValue`绛変簬`oldValue`//鍥犱负瀹冧滑鏄悓涓€涓璞★紒})obj.count++鐩稿弽锛屼竴涓猤etter鍑芥暟杩斿洖涓€涓搷搴斿紡瀵硅薄浠呭湪瀵硅薄琚浛鎹㈡椂瑙﹀彂锛歝onstobj=reactive({someString:'hello',someObject:{count:0}})watch(()=>obj.someObject,()=>{//浠呭湪obj.someObject琚浛鎹)褰撶劧锛屼綘涔熷彲浠ユ樉寮忓湴娣诲姞deep閫夐」鏉ュ己鍒朵竴涓繁搴︾洃鍚櫒锛歸atch(()=>obj.someObject,(newValue,oldValue)=>{//杩欓噷鐨刞newValue`绛変簬to`oldValue`//闄ら潪obj.someObject琚畬鍏ㄦ浛鎹onsole.log('deep',newValue.count,oldValue.count)},{deep:true})obj.someObject.count++//deep11鐩戝惉鍙嶅簲瀵硅薄鎴朼r灏勭嚎锛屾柊鍊肩瓑浜庢棫鍊笺€備负浜嗚В鍐宠繖涓棶棰橈紝鎴戜滑鍙互鍋氬€尖€嬧€嬬殑娣辨嫹璐濄€倃atch(()=>_.cloneDeep(obj.someObject),(newValue,oldValue)=>{//姝ゆ椂`newValue`涓嶇瓑浜巂oldValue`console.log('deep',newValue.count,oldValue.count)},{deep:true})obj.someObject.count++//deep10娉ㄦ剰锛氭繁搴︾洃鍚渶瑕侀亶鍘嗘墍鏈夊祵濂楀睘鎬э紝褰撴暟鎹粨鏋勫簽澶ф椂锛屽紑閿€闈炲父澶с€傛墍浠ユ垜浠璋ㄦ厧浣跨敤锛屾敞鎰忔€ц兘銆倃atchEffectwatch()鏄儼鎬х殑锛氬洖璋冧粎鍦ㄦ暟鎹簮鍙戠敓鍙樺寲鏃舵墽琛屻€備絾鏄湪鏌愪簺鍦烘櫙涓嬶紝鎴戜滑甯屾湜鍦ㄥ垱寤虹洃鍚櫒鏃剁珛鍗虫墽琛屽洖璋冦€傚綋鐒朵篃鍙互浣跨敤immediate閫夐」鏉ュ疄鐜帮細consturl=ref('https://...')constdata=ref(null)asyncfunctionfetchData(){constresponse=awaitfetch(url.value)data.value=awaitresponse.json()}//绔嬪嵆鎵ц涓€娆★紝鐒跺悗鐩戝惉url鍙樺寲watch(url,fetchData,{immediate:true})鍙互鐪嬪埌watch浣跨敤浜嗕笁涓弬鏁帮紝鎴戜滑鍙互浣跨敤watchEffect鏉ョ畝鍖栦笂闈㈢殑浠g爜銆倃atchEffect浼氱珛鍗虫墽琛屽洖璋冨嚱鏁般€傚鏋滄鏃跺嚱鏁颁骇鐢熶簡鍓綔鐢紝Vue浼氳嚜鍔ㄨ窡韪壇浣滅敤鐨勪緷璧栧叧绯伙紝鑷姩鍒嗘瀽鐩戝惉鐨勬暟鎹簮銆備笂闈㈢殑渚嬪瓙鍙互閲嶅啓涓猴細consturl=ref('https://...')constdata=ref(null)//涓€涓弬鏁板彲浠ュ鐞唚atchEffect(async()=>{constresponse=awaitfetch(url.value)data.value=awaitresponse.json()})watchEffect鎺ュ彈涓や釜鍙傛暟锛岀涓€涓弬鏁版槸鏁版嵁鍙樺寲鏃舵墽琛岀殑鍥炶皟鍑芥暟锛岀敤娉曞拰watch涓€鏍枫€傜浜屼釜鍙傛暟鏄彲閫夊璞★紝鏀寔flush鍜宱nTrack/onTrigger閫夐」锛屽姛鑳藉悓watch銆傛敞鎰忥細watchEffect鍙細鍦ㄥ叾鍚屾鎵ц鏈熼棿璺熻釜渚濊禆椤广€備娇鐢ㄥ紓姝ュ洖璋冩椂锛屽彧浼氳窡韪湪绗竴娆wait涔嬪墠璁块棶鐨勪緷璧栭」銆倃atchvs.watchEffectwatch鍜寃atchEffect鐨勪富瑕佸姛鑳芥槸涓€鏍风殑锛岄兘鍙互鍝嶅簲寮忕殑鏂瑰紡鎵ц鍥炶皟鍑芥暟銆傚畠浠殑鍖哄埆鍦ㄤ簬璺熻釜鍙嶅簲渚濊禆鐨勬柟寮忥細watch鍙窡韪槑纭畾涔夌殑鏁版嵁婧愶紝涓嶈窡韪洖璋冧腑璁块棶鐨勪笢瑗匡紱榛樿鎯呭喌涓嬶紝鍥炶皟浠呭湪鏁版嵁婧愭洿鏀规椂瑙﹀彂锛泈atch鍙互璁块棶鐩戝惉鏁版嵁鐨勬柊鏃у€笺€倃atchEffect浼氳鍒濆鍖栦竴娆★紝鍦╯ideeffects鏈熼棿璺熻釜渚濊禆鍏崇郴锛屽苟鑷姩鍒嗘瀽鐩戝惉鐨勬暟鎹簮锛泈atchEffect鏃犳硶璁块棶鐩戝惉鏁版嵁鐨勬柊鏃у€笺€傛€昏€岃█涔嬶紝watch鏇村己澶э紝鑰寃atchEffect鍦ㄦ煇浜涘満鏅笅鏇寸畝娲併€傚ソ浜嗭紝浠婂ぉ鐨勫垎浜氨鍒拌繖閲屻€備笉鐭ラ亾澶у瀵箇atch鍜寃atchEffect鏈夋病鏈夋繁鍏ョ殑浜嗚В銆傛杩庡湪璇勮鍖虹暀瑷€锛佽寰楁湁鐢ㄨ寰楃偣璧炴敮鎸佸摝~馃尮馃尮鍙傝€冩枃妗o細Vue3瀹樼綉