学习笔记Vue3-watch属性(尚硅谷)

229 阅读4分钟

watch监视

导入watch

import {watch} from 'vue'

情况1

监视【ref】定义的【基本】类型

<h1>情况1-监视【ref】定义的基本【类型】</h1>
<h2>当前求和sum为{{ sum }}</h2>
<button @click="add">点我sum加1</button>
<hr />

数据和方法

//数据	
let sum = ref(0);
//方法
function add(){
    sum.value+=1;
}

watch

watch(sum,(newVal,oldVal)=>{
    console.log('sum改变了',newVal,oldVal);
})

注意,这里监视不用sum.value

可以把watch赋为一个变量

const stopWatch=watch(sum,(newVal,oldVal)=>{
	console.log('sum改变了',newVal,oldVal);
    if(newVal>10){
        stopWatch();//新值到达10结束监视
    }
})

情况2

情况2-监视【ref】定义的对象【类型】

<h1>情况2-监视【ref】定义的对象【类型】</h1>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changePerson">修改人</button>

数据和方法

//数据  
let person = ref({ name: "张三", age: 20 });
//方法
function changeName() {
    person.value.name += "~";
}
function changeAge() {
    person.value.age += 1;
}
function changePerson() {
    person.value = { name: "李四", age: 25 };
}

监视

watch(person,(newVal,oldVal)=>{
    console.log("person值改变了", newVal, oldVal);
},{deep:true})

ref定义的对象类型,监视的为对象的地址值,如果想监视对象内部属性的变化,需要我们手动开启深度监视,大多数时候我们不需要管理旧值,所以我们只需要监视新的值就好了

immediate可以在开始的时候进行一次监视,deep可以开启深度监视(true/false)

情况三

情况3-监视【reactive】定义的对象【类型

<h1>情况3-监视【reactive】定义的对象【类型】</h1>
<h2>姓名:{{ person1.name1 }}</h2>
<h2>年龄:{{ person1.age1 }}</h2>
<button @click="changeName1">修改名字</button>
<button @click="changeAge1">修改年龄</button>
<button @click="changePerson1">修改人</button>

数据和方法

function changeName1() {
    person1.name1 += "~";
}
function changeAge1() {
    person1.age1 += 1;
}
function changePerson1() {
    //通过数组方法来分配
    Object.assign(person1, { name1: "李四", age1: 25 });
}

注意,这里我修改整个对象的时候,我不能够这样写

function changePerson1() {
    person1 = {name1:'李四',age1:25}
}

这样是不能够进行响应式的修改的,需要借助assign方法来将一个新的对象值给person1从而覆盖掉原来的值。

监视

watch(person1, (newVal, oldVal) => {
    console.log("person1值改变了", newVal, oldVal);
  });

区别ref定义的对象类型

reactive:

1. 默认开启深度监视
	2. 隐式的创建了深度监听
	3. 这种深度监听是无法关掉的

我们没有定义新的对象,地址值是没有发生改变的,只是在修改原对象person1里面的数据而已

情况四

情况4-监视【reactive】用来监视对象内部属性的变化

<h1>情况4/5-监视【reactive】定义的对象【类型】(对象中的某个属性)</h1>
<h2>姓名:{{ person2.name2 }}</h2>
<h2>年龄:{{ person2.age2 }}</h2>
<h2>车型:{{ person2.car.c1 }} {{ person2.car.c2 }}</h2>
<button @click="changeName2">修改名字</button>
<button @click="changeAge2">修改年龄</button>
<button @click="changeC1">修改车型1</button>
<button @click="changeC2">修改车型2</button>
<button @click="changeCar">修改整个车</button>

数据和方法

//4 5
function changeName2() {
    person2.name2 += "~";
}
function changeAge2() {
    person2.age2 += 1;
}
function changeC1() {
    person2.car.c1 = "奥迪";
}
function changeC2() {
    person2.car.c2 = "大众";
}
function changeCar() {
    person2.car = {
        c1: "雅迪",
        c2: "艾玛",
    };
}

监视

监视对象中内部属性的变化,监视响应式对象的某个属性,且属性为基本类型,要写成函数式

例如,对person2的name2属性进行监视

watch(
    () => person2.name2,
    (newVal, oldVal) => {
        console.log("person2值改变了", newVal, oldVal);
    },
);

这里我写的是箭头函数的简写形式

通过这种方法可以监视内部属性的变化,倘若需要监视person2中的car内部的变化呢?

watch(
    () => person2.car,
    (newVal, oldVal) => {
        console.log("person2.car值改变了", newVal, oldVal);
    },
    { deep: true },
);

建议都写成函数式

注意点:若监视的式对象的地址值,需要手动深度监视

情况5

监视多个数据reactive

watch(
    [
        () => person2.name2,
        () => person2.age2,
        () => person2.car.c1,
        () => person2.car.c2,
    ],
    //这里的新旧值是他们组成的数组
    (newvalues, oldvalues) => {
        console.log("person2值改变了", newvalues, oldvalues);
    },
);

也能使用es6的解构写法,对监视的数据分别指配进行后续的操作

watchEffect

导入

import {watchEffect} from 'vue'

引出

需求:当水位超过60度和水位到达80cm的时候,发送请求。

结构

<h2>需求:当水位超过60度或者水位达到80cm的时候,给服务器发送请求</h2>
<h2>当前水温为{{ temp }}C</h2>
<h2>当前水位为{{ height }}cm</h2>
<button @click="changeTemp">水温加10</button>
<button @click="changeHeignt">水位加10</button>

数据和方法

//数据
let temp = ref(10);
let height = ref(0);
//方法
function changeTemp() {
    temp.value += 10;
}
function changeHeignt() {
    height.value += 10;
}

我们可以使用watch解决这个问题

//监听watch实现
watch([temp, height], (value) => {
    //解构
    let [newtemp, newheight] = value;
    if (newtemp >= 60 || newheight >= 80) {
        console.log("发送请求");
    }
});

发现用watch要监视这两个属性,我们就需要告诉watch监视的是什么。

此时可以使用watchEffect

watchEffect(() => {
    if (temp.value >= 60 || height.value >= 80) {
        console.log("发送请求");
    }
});

watchEffect一上来就会执行一下回调函数,会自动监视依赖的变量,一旦变化就会立即执行回调函数。