文章目录
- 1.watch
- 1.侦听数据源类型
- 2.demo
- 2.watchEffect函数
- 3.watch vs. watchEffect
1.watch
计算属性允许我们声明性地计算衍生值。然而在有些情况下,我们需要在状态变化时执行一些“副作用”:例如更改 DOM,或是根据异步操作的结果去修改另一处的状态。
在组合式 API 中,我们可以使用 watch 函数在每次响应式状态发生变化时触发回调函数.
- 与Vue2.x中watch配置功能一致
1.侦听数据源类型
watch 的第一个参数可以是不同形式的“数据源”:它可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组.
-
两个小“坑”:
- 监视reactive定义的响应式数据时 :oldValue无法正确获取、强制开启了深度监视(deep配置失效)。
- 监视reactive定义的响应式数据中某个属性时:deep配置有效。
2.demo
<template>
<div>
<h3>watch和watchEffect</h3>
<input type="text" v-model="bir" placeHolder="请输入出生年月" >
<p>当前的周岁年龄为:{{age}}</p>
<input type="text" v-model="firstName" >+
<input type="text" v-model="lastName">=
<input type="text" v-model="fullName">
<input type="text" v-model="people.name">
<input type="text" v-model="people.age">
<input type="text" v-model="people.job.salary">
</div>
</template>
<script setup>
import {ref,watch,reactive,watchEffect} from "vue"
const bir=ref("2018/5/20");
const age=ref(0);
//1.watch监听单个ref数据
watch(bir,(newValue,oldValue)=>{
console.log("监听到了txt的变化")
console.log(newValue,oldValue);
age.value=new Date().getFullYear()-new Date(bir.value).getFullYear();
})
//2.监视多个ref定义的响应式数据
const firstName=ref("张");
const lastName=ref("三");
const fullName=ref("张三")
/**
watch([firstName,lastName],(newValue,oldValue)=>{
console.log(newValue,oldValue)
//newValue:[第一个监听数据的最新值,第二个监听数据的最新值,....]
//oldValue:[第一个监听数据的上一次操作的值,第二个监听数据的上一次操作的值,....]
fullName.value=newValue[0]+newValue[1];
})
**/
watchEffect(()=>{
fullName.value=firstName.value+lastName.value
})
//3.监视reactive定义的响应式数据
// 若watch监视的是reactive定义的响应式数据,则无法正确获得 oldValue!!
// 若watch监视的是reactive定义的响应式数据,则强制开启了深度监视
const people=reactive({
name:'张三',
age:13,
job:{
address:'中山西路',
salary:"40k"
}
})
/**
watch(people,(newValue,oldValue)=>{
console.log("监听people对象");
console.log(newValue,oldValue);
},{deep:false})//此处的deep配置不再奏效
**/
//4.监视reactive定义的响应式数据中的某个属性
watch(()=>people.job,(newValue,oldValue)=>{
console.log('person的job变化了',newValue,oldValue)
},{deep:true}) // 特殊情况.此处由于监视的是reactive定义的对象中的某个属性,所以deep配置有效
//5.监视reactive定义的响应式数据中的某些属性
//这时newValue,oldValue又可以正常使用了
watch([()=>people.name,()=>people.age],(newValue,oldValue)=>{
console.log('person的name变化了',newValue,oldValue)
},{immediate:true,deep:true})
</script>
2.watchEffect函数
-
watch的套路是:既要指明监视的属性,也要指明监视的回调。
-
watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。
-
watchEffect有点像computed:
- 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
- 而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
watchEffect(()=>{
const x1 = sum.value
const x2 = person.age
console.log('watchEffect配置的回调执行了')
})
3.watch vs. watchEffect
watch 和 watchEffect 都能响应式地执行有副作用的回调。它们之间的主要区别是追踪响应式依赖的方式:
watch 只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西。另外,仅在数据源确实改变时才会触发回调。watch 会避免在发生副作用时追踪依赖,因此,我们能更加精确地控制回调函数的触发时机。
watchEffect,则会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。这更方便,而且代码往往更简洁,但有时其响应性依赖关系会不那么明确。