既然是資料監聽,監聽的是它的變化。那就需要能夠捕捉它的變更,於是監聽的資料必然要是響應式資料
watch(WatcherSource, Callback, [WatchOptions])
參數:
WatcherSource:想要監聽的響應式資料。
Callback:執行的回呼函數,入參(newValue,oldValue)。
[WatchOptions]:deep、immediate、flush可選。
對於WatchOptions的參數配置:
deep:當需要對物件等引用類型資料進行深度監聽時,設定deep: true,預設值是false。
immediate:預設情況下watch是惰性的,當設定immediate: true時,watch會在初始化時立即執行回呼函數一次。
flush:控制回呼函數的執行時機,。它可設定為 pre、post 或 sync。
pre:預設值,當監聽的值發生變更時,優先執行回呼函數(在dom更新之前執行)。
post:dom更新渲染完畢後,執行回呼函數。
sync:一旦監聽的值發生了變化,同步執行回呼函數(建議少用)。
const count = ref(1); watch(count, (newValue, oldValue) => { console.log('值发生了变更', newValue, oldValue); });
可以取得到新值和舊值。
const count = ref({ a: 1, b: 2 }); const handleClick = function () { count.value.a = 5; }; watch(count, (newValue, oldValue) => { console.log('值发生了变更', newValue, oldValue); });
即使整個陣列作為引用資料型別被監聽,它內部的某一項發生變更也不會被觀察到。所以watch中的程式碼並沒有執行。
此時,就需要使用深度監聽:deep:true
const count = ref({ a: 1, b: 2 }); const handleClick = function () { count.value.a = 5; }; watch( count, (newValue, oldValue) => { console.log('值发生了变更', newValue, oldValue); }, { deep: true } );
值發生了變更Proxy {a: 5, b: 2} Proxy {a: 5, b: 2}
可以注意到的是,深度監聽的需要是這個引用資料型別自身,而不是其中的屬性。並且,他只能取得到新值,而取得不到舊的值。
const count = ref({ a: 1, b: 2 }); const handleClick = function () { count.value.a = 5; }; watch( () => { return { ...count.value }; }, (newValue, oldValue) => { console.log('值发生了变更', newValue, oldValue); }, { deep: true } );
這樣把watch的引用型別資料來源深拷貝一份,即可完成對新舊值得取得:
##三,監聽單一資料:reactive#值發生了變更{a: 5, b: 2} {a: 1, b: 2}
const single = reactive({ count: 1, test: 2 }); const handleClick = function () { single.count++; }; watch( () => single.count, (newValue, oldValue) => { console.log('值发生了变更', newValue, oldValue); }, { immediate: true } );
<template> <div class="mine-box"> <div ref="countDom">{{ single.count }}</div> <button @click="handleClick">按钮</button> </div> </template> <script setup> import { ref, reactive, watch } from 'vue'; const single = reactive({ count: 1, test: { a: 1, b: 2 } }); const handleClick = function () { single.test.a++; }; watch( single, (newValue, oldValue) => { console.log('值发生了变更', newValue, oldValue); }, { immediate: true } ); </script>
設定immediate: true時,watch會在初始化時立即執行回調函數
。
const count = ref(1); const handleClick = function () { count.value++; }; watch( count, (newValue, oldValue) => { console.log('值发生了变更', newValue, oldValue); }, { deep: true, immediate: true } );
const count = ref(1); const double = ref(2); const handleClick = function () { count.value++; double.value++; }; watch( [count, double], (newValue, oldValue) => { console.log('值发生了变更', newValue, oldValue); }, { deep: true, immediate: true } );
<template> <div class="mine-box"> <div ref="countDom">{{ count }}</div> <button @click="handleClick">按钮</button> </div> </template> <script setup> import { ref, watch } from 'vue'; const count = ref(1); const countDom = ref(null); const handleClick = function () { count.value++; }; watch( count, (newValue, oldValue) => { console.log('---', countDom.value.textContent); console.log('值发生了变更', newValue, oldValue); }, { deep: true } ); </script>
--- 1值發生了變更2 1在回呼函數中,新的值已經變成了2,但得到的DOM仍然是之前的。預設情況下,flush的值為pre。當值發生變化時,回呼函數將在DOM更新之前觸發執行。 2,flush: 'post’在dom渲染完畢後執行回呼函數
<template> <div class="mine-box"> <div ref="countDom">{{ count }}</div> <button @click="handleClick">按钮</button> </div> </template> <script setup> import { ref, watch } from 'vue'; const count = ref(1); const countDom = ref(null); const handleClick = function () { count.value++; }; watch( count, (newValue, oldValue) => { console.log('---', countDom.value.textContent); console.log('值发生了变更', newValue, oldValue); }, { deep: true, flush: 'post' } ); </script>
--- 2值發生了變更2 1當回呼函數被呼叫時,DOM已經更新完成,此時取得到的DOM是經過資料變更後更新完成的DOM。
以上是vue3下的watch怎麼使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!