携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情
在开发时,总是需要监听某些数据变化,再根据数据的变化进行响应, Vue3 中既可以使用 watch 也可以使用 watchEffect,那么他们俩该怎么使用,又有什么区别呢?
一、 watch
在 Vue2 中,我们通过这样的方式来实现一个监听:
Vue3 实现方式
watch 接收的参数有三个:
- 需要监听的响应式的数据或对象,如reactive、ref 定义的响应式数据
- 对象内部属性变化的回调函数,可获取新、旧两个形式参数
- 属性控制(可省略):
- deep :是否深度监听
- immediate :启动页面后是否立即开始监听
在监听时,一个普通的变量和对象参数略有不同:
1. 监听 ref
watch(dataName, (newVal, oldVal) => {
console.log(newVal); console.log(oldVal);
}, {
deep: true,
immediate: true
})
2. 监听 reactive
监听对象或者对象属性的的时候,第一个是回调函数,目的是监听数据的getter()
第一个参数的形式:
- ( ) => data 或
- ( ) =>data.name
watch(() => data.name, (newVal, oldVal) => {
console.log(newVal); console.log(oldVal);
}, {
deep: true,
immediate: true
})
3. 监听多个值的变化
- 如果多个数据同时发生改变,watch只触发一次
- 输出的结果 newVal 是一个数组,里面包含了 data1 和 data2 改变后的数据
watch(
() => [data1, data2],
(newVal, oldVal) => {
console.log(newVal, '更新后的数据')
}
)
watchEffect 监听
watchEffect
只有一个回调函数作为参数,监听的是回调函数中所有用到的数据(类似computed)- 可以立即执行传入的函数,监听引用数据类型的所有属性(不需要具体到某个属性)
- 只能获取当前值,也就是更新后的值
watchEffect(() => {
console.log(data.name, 'watchEffect触发')
})
取消监听
调用 watch 本身,可以实现取消监听
const myWatch = watch( name, () => {
// TODO
})
myWatch()
总结
对比上面的写法,不难看出,watch 和 watchEffect 之间的区别:
- watch 需要声明依赖源,watchEffect 自动收集依赖源
- watch 是惰性的,在页面第一次加载时不触发,只有监听的数据发生变化时触发,可配置
immediate: true
让其立即执行。watchEffect 是非惰性的,在页面第一次加载时就会触发。 - watch 可以获取更新前后的值,watchEffect 只能获取更新后的值