watch侦听器
watch需要侦听特定的数据源,并在单独的回调函数中执行副作用
watch的第一个参数监听源,第二个参数为回调函数cb(newVal,oldVal),第三个参数一个options配置项是一个对象
// watch第三个参数
{
immediatte:true, // 是否立即调用一次
deep:true // 是否开启深度监听
}
创建一个ref,并对其进行监听,通过打印可以看到watch侦听到了数据的变化
watch还可以一次性监听多个源,只需要往第一个参数传入一个数组
如果用来监听一个深层次的对象,可以发现控制台并没有打印,没有成功监听到
一个方法就是使用前面的方法,将ref修改为reactive
另一种方法就是给watch传入第三个参数,来允许监听深层次
可以看到两种监听深层次的方法旧值都没有正确地输出出来,这应该是vue3存在的bug
我们也可以监听reactive的单一值
watchEffect高级侦听器
watchEffect用于立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。
如果用到message 就只会监听message 就是用到几个监听几个 而且是非惰性 会默认调用一次
可以看到页面加载的时候就立即调用了一次,不像watch只有值改变才调用
清除副作用
就是在触发监听前会调用一个函数可以处理你的代码逻辑
停止跟踪 watchEffect
停止跟踪会返回一个函数 调用之后将停止更新
可以看到通过触发stopWatch函数后,监听事件就失效了
回调的触发时机
可以看到拿到了null,这是因为dom此时还未加载
默认情况下,用户创建的侦听器回调,都会在 Vue 组件更新之前被调用。这意味着你在侦听器回调中访问的 DOM 将是被 Vue 更新之前的状态。
如果想在侦听器回调中能访问被 Vue 更新之后的DOM,你需要指明 flush: 'post'
选项:
可以看到成功获取了更新后的DOM
更多的配置项
副作用刷新时机 flush 一般使用post
pre | sync | post | |
---|---|---|---|
更新时机 | 组件更新前执行 | 强制效果始终同步触发 | 组件更新后执行 |
watch和watchEffect总结
watch
和 watchEffect
都能响应式地执行有副作用的回调。它们之间的主要区别是追踪响应式依赖的方式:
watch
只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西。另外,仅在数据源确实改变时才会触发回调。watch
会避免在发生副作用时追踪依赖,因此,我们能更加精确地控制回调函数的触发时机。watchEffect
,则会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。这更方便,而且代码往往更简洁,但有时其响应性依赖关系会不那么明确。