一、監聽方法
vue3中定義的變量默認不是響應式的,所以只能監聽用ref和reactive定義的數據和變量。
監聽前要確保引入相關依賴ref、reactive、watch:
<script setup lang="ts"> import { ref,watch,reactive } from 'vue'; </script>
1、監聽單個值的變化:
通過ref定義一個變量testText,並將這個值和文本框綁定,對這個值進行監聽:
<script setup lang="ts"> import { ref,watch,reactive } from 'vue'; let testText = ref<string>("testText"); watch(testText,(newValue,OldValue) => { console.log(newValue); console.log(OldValue); }); </script> <template> <input type="text" v-model="testText" /> </template>
2、監聽多個值的變化:
通過ref定義兩個變量testText、testContent,並將這兩個值和文本框綁定,對這兩個值進行監聽:
<script setup lang="ts"> import { ref,watch,reactive } from 'vue'; let testText = ref<string>("testText"); let testContent = ref<string>("testContent"); watch([testText,testContent],(newValue,OldValue) => { console.log(newValue); console.log(OldValue); }); </script> <template> <input type="text" v-model="testText" /> <input type="text" v-model="testContent" /> </template>
多個監聽值的時候,輸出的監聽結果新值和舊值也是多個:
3、監聽表單變化:
通過reactive創建一個表單testText ,並將其內部的屬性title與文本框綁定,對表單整體進行監聽:
<script setup lang="ts"> import { ref,watch,reactive } from 'vue'; let testText = reactive({ title:"標題" }); watch(testText,(newValue,OldValue) => { console.log(newValue); console.log(OldValue); }); </script> <template> <input type="text" v-model="testText.title" /> </template>
得到的結果如下:
注:從這裏可以看出,當表單的內部屬性發生變化後,監聽表單整體時是拿不到修改前的值。
而且監聽表單整體時默認watch自動開啓了deep屬性,即深度監聽。
4、監聽表單下的屬性值:
通過reactive創建一個表單testText ,並將其內部的屬性title與文本框綁定,對表單內部的title屬性進行單獨監聽:
<script setup lang="ts"> import { ref,watch,reactive } from 'vue'; let testText = reactive({ title:"標題" }); watch(() => testText.title,(newValue,OldValue) => { console.log(newValue); console.log(OldValue); }); </script> <template> <input type="text" v-model="testText.title" /> </template>
得到的結果如下:
這次新值和舊值都打出來了,單獨監聽的話是可以取到舊值的。
注:監聽內部的時候需要使用 () => 來指向,如果是獨立的單個定義值的話,也可以通過這個前綴加屬性名稱加.value來監聽。
5、監聽多層嵌套表單下的表單:
通過reactive創建一個表單testText ,並將其內部的表單form裏的title屬性值與文本框綁定,對表單內部的form表單整體進行監聽:
<script setup lang="ts"> import { ref,watch,reactive } from 'vue'; let testText = reactive({ form:{ title:"標題" } }); watch(() => testText.form,(newValue,OldValue) => { console.log(newValue); console.log(OldValue); },{ deep:true }); </script> <template> <input type="text" v-model="testText.form.title" /> </template>
這裏就要在監聽時候加上deep屬性並配置爲true,通過深度監聽才能監聽到內部表單的變化,而且因爲是監聽的表單,同樣無法拿到舊值。
二、監聽屬性
1、是否立即執行(immediate):
這是個布爾類型值,true和false代表是否開啓該屬性。默認爲false即關閉,而開啓和關閉的區別在於,監聽是否要在初始化的時候觸發。
例如,定義一個字符串值的時候,默認爲”初始值”,然後將其修改爲”修改值”,此時會產生差異:
true:會先在初始化爲“初始值”時觸發一次監聽,再在值調整爲“修改值”時觸發第二次監聽。
false:初始化爲“初始值”時不觸發,在值調整爲“修改值”時觸發第一次監聽。
2、是否深度監聽(deep):
主要用於監聽多層嵌套的表單內部表單,默認爲false關閉,需要監聽時屬性可以設置爲true。
三、無指向監聽
watch的監聽需要三個參數,分別是監聽的數據內容、監聽回調函數方法、監聽配置屬性。
而watchEffect不同,它不需要指定監聽的數據內容,會根據回調函數方法裏用到的數據,自動去監聽這些內容,且immediate和deep兩個屬性都默認爲開啓狀態。
<script setup lang="ts"> import { ref,watch,reactive, watchEffect } from 'vue'; let testText = reactive({ form:{ title:"watchEffect" } }); watchEffect(() => { console.log(testText.form.title); }); </script> <template> <input type="text" v-model="testText.form.title" /> </template>
得到的結果如下: