从零开始的手写 Vue.js 响应式系统 —— effect(三)
2023-09-08 06:51:15
在上一篇中,我们使用 effect
函数实现了 computed
的懒执行和缓存机制。在这篇文章中,我们将继续深入探索 effect
函数的强大功能,实现 watch
的立即执行以及支持两种形式的观测。
从 computed
到 watch
computed
和 watch
都是 Vue.js 中常用的响应式特性,它们允许我们在数据变化时执行特定的操作。computed
主要用于计算派生数据,而 watch
则更通用,可以监听任何数据的变化。
从实现原理上来看,computed
其实就是一种特殊的 watch
。computed
会在数据变化时自动触发重新计算,而 watch
则需要手动调用 effect
函数来触发。
effect
中的立即执行
默认情况下,effect
函数会在数据变化后立即执行。但是,我们可以通过设置 scheduler
选项来延迟 effect
的执行。
effect(() => {
// 延迟执行的代码
}, { scheduler: () => setTimeout(() => {}, 0) });
在上面的代码中,effect
函数中的代码会在数据变化后延迟执行。scheduler
选项是一个回调函数,它指定了 effect
函数的执行时机。
两种形式的观测
Vue.js 中的响应式系统支持两种形式的观测:
- 追踪依赖: 当一个函数被执行时,它会追踪它所依赖的数据。如果这些数据发生变化,则函数会被重新执行。
- 手动触发: 可以通过调用
effect
函数来手动触发一个函数的执行。
实现 watch
我们可以利用 effect
函数的立即执行和手动触发的特性来实现 watch
。
function watch(source, callback) {
let oldValue;
effect(() => {
const newValue = source();
if (newValue !== oldValue) {
callback(newValue, oldValue);
oldValue = newValue;
}
}, { immediate: true });
}
在上面的代码中,我们使用 effect
函数来监听 source
的变化。当 source
发生变化时,effect
函数中的代码会被立即执行。如果新旧值不相等,则会调用 callback
函数,并更新 oldValue
的值。
示例
下面是一个使用 watch
函数的示例:
const count = ref(0);
watch(count, (newValue, oldValue) => {
console.log(`Count changed from ${oldValue} to ${newValue}`);
});
在上面的示例中,我们使用 watch
函数来监听 count
的变化。当 count
发生变化时,控制台会打印出新旧值。
总结
通过利用 effect
函数的强大功能,我们可以实现 computed
和 watch
的响应式特性。computed
主要用于计算派生数据,而 watch
则更通用,可以监听任何数据的变化。通过理解这两种响应式特性的实现原理,我们可以更深入地了解 Vue.js 的响应式系统。