vue中的watch函数用于监视数据的变化
vue2中的监视
<script src="../../node_modules/vue/dist/vue.js"></script>
<div id="app">
<div>
<button @click="updataHello">更改欢迎词</button>
<button @click="updataObj">更改Obj</button>
<hr>
<p>{{str}}</p>
<hr>
<p>{{info}}</p>
</div>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
info: {
num: 0,
o: {
arr: ['1', 2],
wage: 3000
}
},
str: 'Hello'
}
},
methods: {
updataHello() {
this.str += ' Vue2!'
},
updataObj() {
this.info.num++;
this.info.o.arr[this.info.o.arr.length] = '233';
this.info.o.wage += 100;
}
},
watch: {
str: {
handler(newValue, oldValue) {
console.log('检测到欢迎词变化');
console.log('newValue: ', newValue);
console.log('oldValue: ', oldValue);
}
},
info: {
handler(newValue, oldValue) {
console.log('检测到对象数据的变化');
console.log('newValue: ', newValue);
console.log('oldValue: ', oldValue);
},
deep: true,
immediate: true
}
}
})
</script>
初始
点击更改基本数据
点击更改引用数据
/*
通过调试发现,原始数据更新时,vue是可以监视到数据的变化,
但是引用数据更新时,vue开启深度监视后也是可以监视到变化。
可是会出现一个问题, 通过监视函数获得的新旧值一致,旧值拿不到真正的旧值。
*/
vue3中的监视
vue3中使用的是监视函数watch 监视的响应式数据分为ref定义的响应式和和reactive定义的响应式
在vue3中使用监视需要使用到watch,需要通过引入模块的方式引入
import {ref, reactive, watch} from 'vue';
定义结构
<template>
<div>
<button @click="updataHello">更改欢迎词</button>
<button @click="updataObj">更改Obj</button>
<hr />
<p>{{ str }}</p>
<p>{{ str2 }}</p>
<hr />
<p>{{ info }}</p>
</div>
</template>
定义数据
setup() {
let str = ref("Hello"),
str2 = ref("http"),
info = reactive({
num: 0,
o: {
arr: ["1", 2],
wage: 3000,
},
}),
str3 = "htp";
function updataHello() {
str.value += " Vue2!";
str2.value = "www";
str3 = 222;
}
function updataObj() {
info.num++;
info.o.arr[this.info.o.arr.length] = "233";
info.o.wage += 100;
}
return { str, str2, info, updataHello, updataObj };
}
watch(str, (newValue, oldValue) => {
console.log("检测到欢迎词变化");
console.log("newValue: ", newValue);
console.log("oldValue: ", oldValue);
});
改变后
检测ref原始数据 — 此数据已经响应式
watch([str, str2], (newValue, oldValue) => {
console.log("检测到基本数据变化");
console.log("newValue: ", newValue);
console.log("oldValue: ", oldValue);
});
改变状态
- 监视情况3
检测通过reactive定义的响应式数据变化
watch(info, (newValue, oldValue) => {
console.log("检测到对象数据的变化");
console.log("newValue: ", newValue);
console.log("oldValue: ", oldValue);
});
更新后
点击更新可以发现 info 数据的改变触发了监视, 但是vue2中只有 开启深度监视才能检测到引用数据的变化,为什么? 原因: vue3中被代理的引用数据会自动开启深度监视(强制),所以当未指定 深度监视时,watch依然能监视引用数据
问题:
和vue2中的监视一样,当监视整个对象的时候,触发监视后我们是拿不到
更新之前的数据的
watch(
() => info.num,
(newValue, oldValue) => {
console.log("检测到info的num属性发生变化");
console.log("newValue: ", newValue);
console.log("oldValue: ", oldValue);
}
);
改变后
这种检测方式是可以拿到响应式数据对象某一项的变化,包括新值和旧值. 不过在使用时需要在watch监视中指定传入以一个参数为函数,函数返回被监视的属性
watch(
[() => info.num, () => info.o.wage],
(newValue, oldValue) => {
console.log("检测到info的num、o.wage属性发生变化");
console.log("newValue: ", newValue);
console.log("oldValue: ", oldValue);
}
);
改变后
和方法4类似, 只不过传入的监视的数据为多个,这时需要指定watch方法第一个参数为一个 监视数组,数组中存放返回监视属性的函数
监视到的新旧值以数组的方式存储
watch(
() => info.o.arr,
(newValue, oldValue) => {
console.log("获取到arr值发生变化");
console.log("oldValue: ", oldValue);
console.log("newValue: ", newValue);
},
{ deep: true }
);
改变后
监视引用数据的引用数据发生变化,需要添加deep深度监视 在watch函数的第三参数位置传入一个配置对象即可
watchEffect 监视 检测所有在监视函数中引用到的响应式数据的变化
watchEffect(() => {
console.log("获取到数据发生变化");
console.log("str: ", str.value);
console.log("str2: ", str2.value);
console.log("info: ", info);
console.log("info.num", info.num);
console.log("info.o.wage", info.o.wage);
console.log("info.o.arr", info.o.arr);
}, {});
改变后
注意单独检测引用数据的某个属性的时候会出现无法监视的情况
|