vue3中的watch
vue3中的watch比起vue2中的watch有了些许的变化,我们使用composition api来写基本数据类型的监视:<template>当前求和为:{{ sum }}<button @click="sum++">点我++</button></template><script>import { ref, watch } from
vue3中的watch比起vue2中的watch有了些许的变化,我们使用composition api来写
基本数据类型的监听,在vue3中被ref定义的数据通常在使用时需要在后面加一个.value,但是这里需要监听整个RefImpl对象才能起作用,所以说在写watch时不需要加.value
<template>
当前求和为:{{ sum }}
<button @click="sum++">点我++</button>
</template>
<script>
import { ref, watch } from "vue";
export default {
name: "App",
setup() {
let sum = ref(0);
watch(sum, (newValue, oldValue) => {
console.log("sum变了", newValue, oldValue);
},{immediate:true});
return {
sum,
};
},
};
</script>
vue3中的watch变成了函数形式,有三个参数,第一个是监听的对象,第二个是监听的回调,由于setup不需要考虑this的指向问题,所以可以直接在watch中写箭头函数,第三个是监听的配置项;如果有两个数据需要监听可以直接写成两个watch函数
watch(sum, (newValue, oldValue) => {
console.log("sum变了", newValue, oldValue);
});
watch(msg, (newValue, oldValue) => {
console.log("msg变了", newValue, oldValue);
});
或者把监听的对象写成一个数组,这样写的话,oldValue和newValue全都会变成数组
watch([sum,msg], (newValue, oldValue) => {
console.log("sum或msg变了", newValue, oldValue);
});
对象使用watch和基本数据类型是一样的,如果使用reactive定义的对象可以直接写,但是使用ref定义的对象需要加.value,这是因为监视对象时要对这个对象的Proxy对象生效,如果用ref来定义对象它的value属性才是这个对象的Proxy。如果写了.value那么他对Proxy的监视默认是深度监视,且无法关闭,配置deep:false无效,如果不写.value这里可以在后面加上deep:true,实现深度监视。
<template>
<h2>姓名:{{ obj.name }}</h2>
<h2>年龄:{{ obj.age }}</h2>
<button @click="obj.age++">年龄加加</button>
<h2>朋友名字:{{obj.friend.name}}</h2>
<h2>朋友年龄:{{obj.friend.age}}</h2>
<button @click="obj.friend.name += '@'">朋友名字变化</button>
</template>
<script>
import { reactive, watch, ref } from "vue";
export default {
setup() {
let obj = reactive({
name: "张三",
age: 20,
friend:{
name:'李四',
age:21
}
});
watch(obj, (newValue, oldValue) => {
console.log("obj改变了", newValue, oldValue);
});
// let obj = ref({
// name: "张三",
// age: 20,
// sex: "男",
// friend:{
// name:'李四',
// age:21
// }
// });
//如果使用ref来定义对象,watch需要写成以下两种形式才能生效
// watch(()=>obj.value, (newValue, oldValue) => {
// console.log("年龄改变了", newValue, oldValue);
// });
// watch(()=>obj, (newValue, oldValue) => {
// console.log("年龄改变了", newValue, oldValue);
// },{deep:true});
return {
obj,
};
},
};
</script>
但是这里对对象的监听又有点问题,数据改变时无法拿到oldValue,使用reactive定义的对象会出现这个问题,由于ref在定义响应式对象时也调用了reactive中的方法,所以这个问题目前还无法直接解决,可以通过直接监听对象中的属性来解决,或者把想要监听的属性通过ref来定义
如果只对对象中的某个属性进行监听,需要把第一个参数写成函数的形式才会生效
watch(()=>obj.age, (newValue, oldValue) => {
console.log("年龄改变了", newValue, oldValue);
});
如果要监听对象中的多个属性可以把第一个参数写成数组的形式
watch([()=>obj.age,()=>obj.name], (newValue, oldValue) => {
console.log("年龄或者名字改变了", newValue, oldValue);
});
但是如果对象是嵌套多层的,直接监听最外侧对象可以检测到整个对象中的数据的变化
watch(obj, (newValue, oldValue) => {
console.log("对象改变了", newValue, oldValue);
});
如果想要检测对象中的对象是否发生变化,直接写是无效的
watch(()=>obj.friend, (newValue, oldValue) => {
console.log("年龄改变了", newValue, oldValue);
});//无法检测friend对象中的数据变化
此时需要加上配置项deep:true,监听奏效
watch(()=>obj.friend, (newValue, oldValue) => {
console.log("朋友改变了", newValue, oldValue);
},{deep:true});
vue3中的监听最好用的还是watchEffect,可以自动识别回调中使用了哪个数据来对该数据进行监听,有点像计算属性,但是computed注重的是计算产生的值,所以需要写返回值,watchEffect注重数据变化时回调函数的执行,不需要返回值。
watchEffect(()=>{
//可以直接写回调的逻辑,用到了哪个数据对哪个数据实现监听,只要回调中写到的数据发生变化,方法就会重新执行一次
})
更多推荐
所有评论(0)