04-vue3侦听器
文章目录
-
- 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.valueconst x2 = person.ageconsole.log('watchEffect配置的回调执行了')
})
3.watch vs. watchEffect
watch 和 watchEffect 都能响应式地执行有副作用的回调。它们之间的主要区别是追踪响应式依赖的方式:
watch 只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西。另外,仅在数据源确实改变时才会触发回调。watch 会避免在发生副作用时追踪依赖,因此,我们能更加精确地控制回调函数的触发时机。
watchEffect,则会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。这更方便,而且代码往往更简洁,但有时其响应性依赖关系会不那么明确。