Vue进阶 | 在 Vue3 中使用 watch

939 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情

在开发时,总是需要监听某些数据变化,再根据数据的变化进行响应, Vue3 中既可以使用 watch 也可以使用 watchEffect,那么他们俩该怎么使用,又有什么区别呢?

一、 watch

在 Vue2 中,我们通过这样的方式来实现一个监听:

image.png

Vue3 实现方式

watch 接收的参数有三个:

  1. 需要监听的响应式的数据或对象,如reactive、ref 定义的响应式数据
  2. 对象内部属性变化的回调函数,可获取新、旧两个形式参数
  3. 属性控制(可省略):
    • 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 只能获取更新后的值