在写一个文章编辑器的时候,由于输入框的值和一个ref对象的属性动态绑定,然后需要监听这个ref对象的属性来改变另外一个ref对象的值,所以就有了这篇博文。
适用场景:
在有些情况下,我们需要在状态变化时执行一些“副作用”:例如更改 DOM,或是根据异步操作的结果去修改另一处的状态。
侦听数据源类型
watch
的第一个参数可以是不同形式的“数据源”:它可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组:
使用方法:
使用 watch
方法
watch
主要用于侦听特定的响应式数据源。当这些数据源发生变化时,回调函数会被触发。
import { ref, watch } from 'vue';
const count = ref(0);
const doubled = ref(0);
watch(count, (newCount) => {
doubled.value = newCount * 2;
});
或者对于对象来说:
import { ref, watch } from 'vue';
const x = ref({'name':'xiaoming',age:14})
// 提供一个 getter 函数
watch(
x,
(newX) => {
console.log(`newX is: ${newX}`)
}
)
但是监听这个对象的属性值的时候,第一个参数需要使用getter函数
import { ref, watch } from 'vue';
const x = ref({'name':'xiaoming',age:14})
watch(
() => x.value.age,
(newAge) => {
console.log(`newAge is: ${newAge}`)
}
)
使用 watchEffect
方法
watchEffect
会自动追踪其回调函数中访问到的所有响应式属性,并在这些属性变化时重新执行回调。它更方便,而且代码往往更简洁。
示例:
import { ref, watchEffect } from 'vue';
const data = ref({ id: 1, no: 2 });
watchEffect(() => {
data.value.id = data.value.id * 10 + data.value.no;
});
watch和watchEffect的区别:
watch
vs. watchEffect
watch
和 watchEffect
都能响应式地执行有副作用的回调。它们之间的主要区别是追踪响应式依赖的方式:
-
watch
只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西。另外,仅在数据源确实改变时才会触发回调。watch
会避免在发生副作用时追踪依赖,因此,我们能更加精确地控制回调函数的触发时机。 -
watchEffect
,则会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。这更方便,而且代码往往更简洁,但有时其响应性依赖关系会不那么明确。
watchEffect方法:
// 使用 watchEffect 自动更新 id 属性
watchEffect(() => {
data.value.id = data.value.id * 10 + data.value.no;
});
watch方法:
// 使用 watch 方法监听 id 和 no 的变化
watch(
[() => data.value.id, () => data.value.no],
([newId, newNo]) => {
data.value.id = newId * 10 + newNo;
}
);
最后
通过上面的示例可以看出,watchEffect
相对 watch
更为简洁。watchEffect
是一种更方便的方式,可以自动追踪依赖,适用于简单的响应式逻辑;而 watch
提供了更多的控制和精确度,适用于复杂的场景。根据具体需求选择合适的方法,以实现最佳效果。