前言
以下文章是我个人学习的输出方式,目的是为了夯实自己的技术基础。
watch()
介绍
watch() 用于侦听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数。
特点
watch() 默认是懒侦听的,即仅在侦听源发生变化时才执行回调函数,只能侦听以下四种数据:
ref定义的数据;reactive定义的数据;- 一个函数,返回一个值(
getter函数); - ...或是由以上类型的值组成的数组;
示例一
监视 ref 定义的【基本类型】数据:直接写数据名即可,监视的是其 value 值的改变。
const count = ref(0)
watch(count, (count, prevCount) => {
/* ... */
})
示例二
监视 ref 定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视。注意点如下:
- 若修改
ref定义的对象中的属性,newValue和oldValue都是新值,因为它们是同一个对象; - 若修改整个
ref定义的对象,newValue是新值,oldValue是旧值,因为不是同一个对象了;
<template>
<div class="person">
<h1>情况二:监视【ref】定义的【对象类型】数据</h1>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changePerson">修改整个人</button>
</div>
</template>
<script lang="ts" setup name="Person">
import { ref, watch } from 'vue'
// 数据
let person = ref({
name: '张三',
age: 18
})
// 方法
function changeName() {
person.value.name += '~'
}
function changeAge() {
person.value.age += 1
}
function changePerson() {
person.value = { name: '李四', age: 90 }
}
// 这种写法,调用 changePerson 会触发,newValue 和 oldValue 是不一样的
// 而调用 changeName 和 changeAge 是不会触发的,需要开启深度监听才行
watch(person, (newValue, oldValue) => {
console.log('person变化了1', newValue, oldValue)
})
// 这种写法,点击按钮都会触发,
// 不同的是,调用 changeName 和 changeAge 触发的 newValue 和 oldValue 是一样的
watch(person, (newValue, oldValue) => {
console.log('person变化了2', newValue, oldValue)
}, { deep: true })
</script>
示例三
监视 reactive 定义的【对象类型】数据,且默认开启了深度监视。
const state = reactive({ count: 0 })
watch(state, () => {
/* 深层级变更状态所触发的回调 */
})
示例四
监视 ref 或 reactive 定义的【对象类型】数据中的【某个属性】,注意点如下:
- 若该属性值不是【对象类型】,需要写成函数形式。
- 若该属性值依然是【对象类型】,可直接编,也可写成函数,建议写成函数。
结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。
const state = reactive({ count: 0 })
watch(
() => state.count,
(count, prevCount) => {
/* ... */
}
)
示例五
监视上述的多个数据
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
/* ... */
})
watchEffect()
介绍
立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。
watch() 对比 watchEffect()
- 都能监听响应式数据的变化,不同的是监听数据变化的方式不同;
watch():要明确指出监视的数据;watchEffect():不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性);
示例
const count = ref(0)
watch(count, (count, prevCount) => {
/* ... */
})
watchEffect(() => console.log(count.value))
// -> 输出 0
count.value++
// -> 输出 1