目錄
手動指定監聽對象
偵聽ref對象
偵聽ref對象中的某個屬性
reactive寫法?
watchEffect?自動偵聽
多源偵聽
一次性偵聽器
手動指定監聽對象
基礎語法:
import { watch, ref } from 'vue'const count = ref(0)// 監聽單個 ref watch(count, (newVal, oldVal) => {console.log(`計數器變化:${oldVal} → ${newVal}`) })// 立即執行版 watch(count, callback, { immediate: true })
偵聽ref對象
<div id="app"><select v-model="a"><option value="10">學生</option><option value="12">老師</option><option value="14">教務</option><option value="16">管理員</option></select></div><script type="module">import { createApp, ref, reactive, watch } from '/vue.esm-browser.js'createApp({setup() {const a = ref("")watch(a, (a, b) => {console.log(a + "-------" + b);})return {a,}}}).mount("#app")</script>
如果匿名函數只有一個參數,則這個參數代表新值。
watch(a, (a) => {
? ? ? ? ? console.log(a);
? ? ? ? })
偵聽ref對象中的某個屬性
<div id="app"><select v-model="a.msg"><option value="10">學生</option><option value="12">老師</option><option value="14">教務</option><option value="16">管理員</option></select>{{a}}</div><script type="module">import { createApp, ref, reactive, watch } from '/vue.esm-browser.js'createApp({setup() {const a = ref({msg: "",obj: ""})watch(() => a.value.msg, (a, b) => {console.log(a + "-------" + b);})return {a,}}}).mount("#app")</script>
注意:參數綁定的是a.msg,監聽的觀察要寫成() => a.value.msg
reactive寫法?
<script type="module">import { createApp, ref, reactive, watch } from '/vue.esm-browser.js'createApp({setup() {const a = reactive({msg: "",obj: ""})watch(() => a.msg, (a, b) => {console.log(a + "-------" + b);})return {a,}}}).mount("#app")
const z = reactive({msg: 0})watch(z, (n, o) => {console.log(n.msg + '---' + o.msg);})
注意:`newValue` 此處和 `oldValue` 是相等的,因為它們是同一個對象
watchEffect?自動偵聽
? ? watchEffect會自動收集所有的依賴,在滿足某個條件時執行。默認情況下會立即執行一次。
? ? watchEffect() 的好處相對較小。但是對于有多個依賴項的偵聽器來說,使用 watchEffect() 可以消除手動維護依賴列表的負擔。此外,如果你需要偵聽一個嵌套數據結構中的幾個屬性,watchEffect() 可能會比深度偵聽器更有效,因為它將只跟蹤回調中被使用到的屬性,而不是遞歸地跟蹤所有的屬性。
<div id="app"><select v-model="a.msg"><option value="10">學生</option><option value="12">老師</option><option value="14">教務</option><option value="16">管理員</option></select>{{a}}</div><script type="module">import { createApp, ref, reactive, watch, watchEffect } from '/vue.esm-browser.js'createApp({setup() {const a = reactive({msg: "1",obj: ""})watchEffect(() => {console.log("監聽開始");if (a.msg == 10) {console.log("學生");}if (a.msg == 12) {console.log("老師");}if (a.msg == 14) {console.log("教務");}console.log("end");})return {a,}}}).mount("#app")
多源偵聽
? ? 根據vue的官方文檔,發現watch可以偵聽多個數據(數組形式),當這個數組中有一個值發生變化,就會執行一次回調函數。
值得一提的是,y
?是一個?ref
,所以直接使用?y
?而不是?() => y.value。
const x = ref(0)const y = ref(0)watch([x, y], ([xn, yn], [xo, yo]) => {console.log(`新值${xn},${yn}`);console.log(`舊值${xo},${yo}`);})
?
一次性偵聽器
注:該功能僅支持 3.4 及以上版本
每當被偵聽源發生變化時,偵聽器的回調就會執行。如果希望回調只在源變化時觸發一次,可以使用once:true
watch(
? source,
? (newValue, oldValue) => {
? ? // 當 `source` 變化時,僅觸發一次
? },
? { once: true }
)?
const z = reactive({msg: 0})
watch(z, (n, o) => {console.log(n.msg + '---' + o.msg);},{ once: true })
?這樣無論偵聽源變換多少次,偵聽器都只會執行一次。