17-watch
作用:监视数据的变化,vue2 中的 watch 作用一致,写法有区别 特点:Vue3 中的 watch 只能监测以下四种数据
- ref 定义的数据
- reactive 定义的数据
- 函数返回的一个值 (getter 函数)
- 一个包含上述内容的数组
监视 ref 定义的基本类型数据
<template>
<div class="child-wrap">
<h3>{{title}}</h3>
求和:{{ sum }}
<br>
<button @click="handleClick">点击</button>
</div>
</template>
<script setup lang="ts">
import { ref , watch} from 'vue';
const title = ref("watch相关")
const sum = ref(0);
function handleClick(){
sum.value += 1
}
watch(sum, (newValue, oldValue)=> {
console.log("sum变化了-新值", newValue);
console.log("sum变化了-旧值", oldValue);
})
</script>
<style lang="" scoped></style>
停止监视方法
const stopWatch = watch(sum, (newValue, oldValue)=> {
console.log("sum变化了-新值", newValue);
console.log("sum变化了-旧值", oldValue);
if(newValue > 5){
stopWatch()
console.log("停止监听");
}
})
监视 ref 定义的对象数据
直接改数据名,监视的是对象的地址值,若要监视对象内部的数据,要手动开启深度监听
- 若修改的是 ref 定义的对象中的属性, newValue 和 oldValue 是一样的都是新值,因为监视的是同一个对象
- 若修改的是整个 ref 定义的对象,newValue 是新值,oldValue 是旧值,因为不是同一个对象
watch
- 第一个参数监视的数据
- 第二个参数 数据变化的回调
- 第三个参数 配置项,可以配置 deep 和 immediate 等其他项
<template>
<div class="child-wrap">
<h3>{{title}}</h3>
<br>
姓名:{{ sum.name }}
<br>
年龄:{{ sum.age }}
<br>
<button @click="handleName">切换姓名</button>
<button @click="handleAge">切换年龄</button>
<button @click="handleSum">切换所有</button>
</div>
</template>
<script setup lang="ts">
import { ref , watch} from 'vue';
const title = ref("watch相关-监视ref定义的对象类型")
const sum = ref({
name: "wang",
age : 18
});
function handleName(){
sum.value.name += "~"
}
function handleAge(){
sum.value.age += 1
}
function handleSum() {
sum.value = {
name: "hahha",
age : 28
}
}
watch(sum, (newVal, oldVal)=> {
console.log("newVal", newVal);
console.log("oldVal", oldVal);
},
{
deep:true
})
</script>
监视 reactive 定义的对象数据
- 监视 reactive 定义的数据,默认开启深度监视,不可关闭 (隐式创建深度监听)
<template>
<div class="child-wrap">
<h3>{{title}}</h3>
<br>
姓名:{{ sum.name }}
<br>
年龄:{{ sum.age }}
<br>
<button @click="handleName">切换姓名</button>
<button @click="handleAge">切换年龄</button>
<button @click="handleSum">切换所有</button>
</div>
</template>
<script setup lang="ts">
import { reactive, ref , watch} from 'vue';
const title = ref("watch相关-监视reactive定义的对象类型")
const sum = reactive({
name: "wang",
age : 18
});
function handleName(){
sum.name += "~"
}
function handleAge(){
sum.age += 1
}
function handleSum() {
Object.assign(sum,{
name: "hahha",
age : 28
})
}
// 监视 reactive 定义的数据,默认开启深度监视
watch(sum, (newVal, oldVal)=> {
console.log("newVal", newVal);
console.log("oldVal", oldVal);
})
</script>
监视reactive/ref定义的数据(对象类型)某个属性
- 若监视的不是对象类型,需要写成函数形式
- 监视的是响应式对象数据的某个属性,且数据是对象类型,可以直接写,也可以写函数,更推荐函数,
结论:监视的是对象里面的属性,最好写成函数,若是对象监视的地址值,需要关注对象内部,需要手动开启深度监听
watch(()=>{return sum.name}, (newVal, oldVal)=> {
console.log("newVal", newVal);
console.log("oldVal", oldVal);
})
或
watch(()=> sum.name, (newVal, oldVal)=> {
console.log("newVal", newVal);
console.log("oldVal", oldVal);
})
- 对象类型,仅监听里面的数据,整个对象变化监听不到
// 只监听对象里面的数据
watch(sum.info, (newVal, oldVal)=> {
console.log("newVal", newVal);
console.log("oldVal", oldVal);
})
- 只监听整个对象,单独的监听不到
watch(()=>sum.info, (newVal, oldVal)=> {
console.log("newVal", newVal);
console.log("oldVal", oldVal);
})
- 开通深度监听, 整个对象新旧值返回的还是不一样的