Vue.js框架:vue3版本里数据变化监听watch和watchEffect的使用
一、监听方法
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>
得到的结果如下: