您好,登錄后才能下訂單哦!
這篇“Vue中的Computed與watch怎么用”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Vue中的Computed與watch怎么用”文章吧。
1、getter必須有返回值
2、computed返回一個只讀響應(yīng)式ref對象 (只讀、響應(yīng)式、對象)
注意:omputed只接收一個getter函數(shù)時,返回的只讀對象,也就是不能修改他的返回值!
getter觸發(fā)條件
1、computed返回值首次被讀取時
2、getter綁定的響應(yīng)式變量被修改時
<script setup> import { ref,computed } from 'vue' const num = ref(1) //computed返回一個只讀響應(yīng)式ref對象computedNum //computedNum是只讀屬性 let computedNum = computed(() => num.value + 1) </script> <template> <p> num:{{ num }} </p> <p>computedNum:{{ computedNum }}</p> <!-- 修改響應(yīng)式變量num 觸發(fā)與之綁定的computed的getter--> <button @click="num++">num++</button> <!-- computedNum是只讀屬性--> <button @click="computedNum++">computedNum++</button> </template>
1、setter函數(shù)對象沒有返回值
2、computed返回一個可讀可寫響應(yīng)式對象
3、setter函數(shù)對象有參數(shù),是getter的返回值,也是computed的值
4、修改computed返回值,觸發(fā)setter函數(shù)對象執(zhí)行,但不會真正修改computed返回值(setter內(nèi)改變getter計算值就會改變computed返回值)
setter觸發(fā)條件
computed返回值被修改時
實例:
<script setup> import { ref, computed } from 'vue' const num = ref(1) //getter(只讀) let computedNum = computed(() => num.value + 1) //getter和setter (可讀可寫) let computedNum2 = computed({ get: () => num.value + 1, set: (val) => { console.log(val); //setter中修改ref響應(yīng)式變量num,將觸發(fā)關(guān)聯(lián)的num的getter計算 //computedNum和computedNum2的getter同時觸發(fā) num.value++ } }) </script> <template> <p> num:{{ num }} </p> <p>computedNum:{{ computedNum }}</p> <p>computedNum2:{{ computedNum2 }}</p> <button @click="num++">num++</button> <!-- computedNum是只讀屬性,會有警告提醒 Write operation failed: computed value is readonly--> <button @click="computedNum++">computedNum++</button> <!-- computedNum2是可讀可寫屬性--> <button @click="computedNum2++">computedNum2++</button> </template>
使用范圍:僅開發(fā)模式生效
computed的第二參數(shù):帶有 onTrack
和 onTrigger
選項的對象
onTrack
:getter關(guān)聯(lián)的響應(yīng)式數(shù)據(jù)時觸發(fā)。
onTrigger
:getter關(guān)聯(lián)的響應(yīng)式數(shù)據(jù)被修改時觸發(fā)
<script setup> import { ref, computed } from 'vue' const num = ref(1) let computedNum = computed(() => num.value + 1, { onTrack: (e) => { console.log('onTrack'); console.log(e); }, onTrigger: (e) => { console.log('onTrigger'); console.log(e); } }) </script> <template> <p> num:{{ num }} </p> <p>computedNum:{{ computedNum }}</p> <!--每次 num++將觸發(fā)onTrigger --> <button @click="num++">num++</button> </template>
語法:
參數(shù)1:觸發(fā)監(jiān)聽回調(diào)函數(shù),回調(diào)函數(shù)可傳入一個onInvalidate函數(shù)作為參數(shù)!
可選參數(shù)2:對象,包含3個可選屬性flush、onTrack、onTrigger
立即執(zhí)行傳入的一個函數(shù),同時響應(yīng)式追蹤其依賴,并在其依賴變更時重新運行該函數(shù)。
1、會立即執(zhí)行一次(和watch的immediate屬性效果一致)
2、關(guān)聯(lián)的響應(yīng)式數(shù)據(jù)被修改時觸發(fā)
3、會自動感知代碼依賴,和watch不一樣,watchEffect會主動綁定監(jiān)聽數(shù)據(jù)
局限性:不能監(jiān)聽對象(但可以監(jiān)聽對象的屬性),只能監(jiān)聽類似ref基本數(shù)據(jù)類型的響應(yīng)式數(shù)據(jù)
<script setup> import { ref, watchEffect } from 'vue' const num = ref(1) //會立即執(zhí)行一次 watchEffect(() => { console.log('watchEffect'); num.value++ }) </script> <template> <p>num: {{ num }}</p> <button @click="num++">num++</button> </template>
隱式:組件卸載時自動停止
顯式:調(diào)用watchEffect
返回值
const stop = watchEffect(() => { /* ... */ }) // 顯式停止 stop()
語法: watchEffect( onInvalidate=>{ onInvalidate(()=>{ }) })
onInvalidate 是一個函數(shù)!優(yōu)先觸發(fā)!
onInvalidate 執(zhí)行時機:
1、watchEffect被重新觸發(fā)時
2、組件卸載時
注意:關(guān)聯(lián)的響應(yīng)式數(shù)據(jù)首次被修改時不會觸發(fā)onInvalidate函數(shù)!
作用: 清理定時器、事件監(jiān)聽removeEventListener 。。。
import { ref, watchEffect } from 'vue' const num = ref(1) watchEffect((onInvalidate ) => { console.log('watchEffect-1'); num.value++ onInvalidate (()=>{ console.log('onInvalidate-2'); }) console.log('watchEffect-3'); }) //1、watchEffect 被重新觸發(fā)時 // onInvalidate-2 // watchEffect-1 // watchEffect-3 //2、組件卸載時 // onInvalidate-2 //3、關(guān)聯(lián)的響應(yīng)式數(shù)據(jù)首次被修改(組件被掛載時) // watchEffect-1 // watchEffect-3
watchPostEffect
和 watchSyncEffect
在Vue3.2新增,是watchEffect類似語法糖的東西,
是watchEffect
可選參數(shù)對象{ flush?: 'pre' | 'post' | 'sync'}
中post和sync的語法糖,pre是默認值
推遲觸發(fā)watchPostEffect
watchPostEffect
是watchEffect可選參數(shù)對象{flush:'post'}
的語法糖
推遲watchEffect觸發(fā)時機!組件更新前觸發(fā)!也就是在生命周期onBeforeUpdate
和 onUpdated
之間觸發(fā)
語法:
//推遲觸發(fā)watchEffect watchEffect( () => { /* ... */ }, { flush: 'post' } ) //Vue3.2語法糖watchPostEffect watchPostEffect(()=>{ /* ... */ })
實例:
//實驗watchEffect第二參數(shù) flush: 'post'屬性 watchEffect(() => { console.log("實驗watchEffect第二參數(shù) {flush: 'post'}屬性"); console.log(obj.age); },{ flush:'post' }) watchEffect(() => { console.log("watchEffect正常時機觸發(fā)"); console.log(obj.age); }) //生命周期onUpdated onUpdated(()=>{ console.log('onUpdated()'); }) //生命周期onBeforeUpdate onBeforeUpdate(()=>{ console.log('onBeforeUpdate()'); })
修改obj.age
時,執(zhí)行結(jié)果:
watchEffect正常時機觸發(fā)
onBeforeUpdate()
實驗watchEffect第二參數(shù) {flush: 'post'}屬性
onUpdated()
同步觸發(fā)watchSyncEffect
watchSyncEffect
是watchEffect可選參數(shù)對象{flush:'sync'}
的語法糖
強制效果始終同步觸發(fā)!效率低!也就是默認watchEffect之前觸發(fā)
語法:
watchEffect( () => { /* ... */ }, { flush: 'sync' } ) //Vue3.2語法糖watchSyncEffect watchSyncEffect(()=>{ /* ... */ })
//假設(shè)修改了對象的屬性值-修改了obj.age const obj = reactive({ name: '小明', age: 18 }) //watchEffect不能監(jiān)聽對象變化 watchEffect(() => { console.log('watchEffect監(jiān)聽對象變化'); console.log(obj); }) //watchEffect可以監(jiān)聽對象屬性變化 watchEffect(() => { console.log('watchEffect監(jiān)聽對象屬性變化'); console.log(obj.age); }) //watch監(jiān)聽對象變化 watch(obj, (obj) => { console.log('watch監(jiān)聽對象變化'); console.log(obj); })
總結(jié):watchEffect
用來監(jiān)聽能監(jiān)聽基本數(shù)據(jù)類型,不能監(jiān)聽對象,但能監(jiān)聽對象的屬性;watch能監(jiān)聽基本數(shù)據(jù)類型和對象!
語法:
參數(shù)1-被監(jiān)聽數(shù)據(jù)(形式:單個數(shù)據(jù)、數(shù)組、帶返回值的回調(diào)函數(shù))
參數(shù)2-觸發(fā)監(jiān)聽的回調(diào)函數(shù),無返回值
可選參數(shù)3-對象{immediate: true,deep:true}
,對象含2個可選參數(shù)和Vue2參數(shù)效果一致
Vue3的watch和Vue2的watch是基本一樣的
1、需要指定監(jiān)聽數(shù)據(jù)
2、惰性,只在被監(jiān)聽數(shù)據(jù)變化時才觸發(fā)(immediate屬性可以設(shè)置在初始化的時候觸發(fā))
參數(shù)1被監(jiān)聽數(shù)據(jù)的形式:
1、單個基本數(shù)據(jù)類型;
2、回調(diào)函數(shù):返回值為單個基本數(shù)據(jù)類型;
// 偵聽一個 getter //被監(jiān)聽數(shù)據(jù)傳入一個帶返回值的回調(diào)函數(shù) const state = reactive({ count: 0 }) watch( () => state.count, (count, prevCount) => { /* ... */ } ) // 直接偵聽一個 ref const count = ref(0) watch(count, (count, prevCount) => { /* ... */ })
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => { /* ... */ })
以下代碼截取官方文檔,從TS代碼可以看出很多關(guān)于watch和watchEffect函數(shù)參數(shù)和返回值的細節(jié)!
computed
只接收一個getter函數(shù)
getter
觸發(fā)條件:
1、computed返回值首次被讀取時
2、getter綁定的響應(yīng)式變量被修改時
computed
同時接收getter函數(shù)對象和setter函數(shù)對象
setter
觸發(fā)條件:computed返回值被修改時
// 只讀的 function computed<T>( getter: () => T, debuggerOptions?: DebuggerOptions ): Readonly<Ref<Readonly<T>>> // 可寫的 function computed<T>( options: { get: () => T set: (value: T) => void }, debuggerOptions?: DebuggerOptions ): Ref<T> interface DebuggerOptions { onTrack?: (event: DebuggerEvent) => void onTrigger?: (event: DebuggerEvent) => void } interface DebuggerEvent { effect: ReactiveEffect target: any type: OperationTypes key: string | symbol | undefined }
參數(shù)1-觸發(fā)監(jiān)聽回調(diào)函數(shù),回調(diào)函數(shù)可傳入一個onInvalidate函數(shù)作為參數(shù)!
可選參數(shù)2-對象,包含3個可選屬性flush、onTrack、onTrigger
function watchEffect( effect: (onInvalidate: InvalidateCbRegistrator) => void, options?: WatchEffectOptions ): StopHandle interface WatchEffectOptions { flush?: 'pre' | 'post' | 'sync' // 默認:'pre' onTrack?: (event: DebuggerEvent) => void onTrigger?: (event: DebuggerEvent) => void } interface DebuggerEvent { effect: ReactiveEffect target: any type: OperationTypes key: string | symbol | undefined } type InvalidateCbRegistrator = (invalidate: () => void) => void type StopHandle = () => void
參數(shù)1-被監(jiān)聽數(shù)據(jù)(形式:單個數(shù)據(jù)、數(shù)組、帶返回值的回調(diào)函數(shù))
參數(shù)2-觸發(fā)監(jiān)聽的回調(diào)函數(shù),無返回值
參數(shù)3-傳入{immediate: true,deep:true}
對象和Vue2參數(shù)效果一致
// 偵聽單一源 function watch<T>( source: WatcherSource<T>, callback: ( value: T, oldValue: T, onInvalidate: InvalidateCbRegistrator ) => void, options?: WatchOptions ): StopHandle // 偵聽多個源 function watch<T extends WatcherSource<unknown>[]>( sources: T callback: ( values: MapSources<T>, oldValues: MapSources<T>, onInvalidate: InvalidateCbRegistrator ) => void, options? : WatchOptions ): StopHandle type WatcherSource<T> = Ref<T> | (() => T) type MapSources<T> = { [K in keyof T]: T[K] extends WatcherSource<infer V> ? V : never } // 參見 `watchEffect` 共享選項的類型聲明 interface WatchOptions extends WatchEffectOptions { immediate?: boolean // 默認:false deep?: boolean }
以上就是關(guān)于“Vue中的Computed與watch怎么用”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。