揭秘Vue.js核心:Computed与Watch,你一定不能错过的源码分析
2023-10-10 11:29:42
Computed与Watch:Vue.js中的双雄争霸
深入浅出,揭秘响应式编程的神秘面纱
在Vue.js的浩瀚世界中,Computed和Watch可谓是两颗璀璨的明珠,它们让响应式编程变得优雅而高效。然而,这两者看似相近,实则各具妙用,本文将深入浅出地剖析它们的本质区别,带你领略Vue.js的核心奥秘。
Computed:依赖的舞者
Computed是一个计算属性,它依赖于其他属性的值而存在。当这些依赖项发生改变时,Computed的值也会随之更新。就像一个舞蹈演员,它时刻关注着音乐的变化,当旋律变幻时,它的舞姿也随之而变。
Watch:敏锐的守望者
与Computed不同,Watch是一个侦听器。它监视某个属性或表达式的变化,一旦侦测到变化,就会执行指定的回调函数。就像一个守望者,它时刻警惕着目标对象的动态,一旦有风吹草动,它便会拉响警报。
三种形态,各显神通
Computed和Watch都有三种不同的形态,分别适用于不同的场景:
1. 计算属性Computed
语法糖:computed
。依赖其他属性的值,当依赖项发生变化时,自动重新计算。
优点:性能优异,仅在依赖项改变时才会重新计算。
缺点:只能访问响应式数据。
2. 侦听器user watcher
语法糖:watch
。监听某个属性或表达式的变化,当变化发生时,触发指定的回调函数。
优点:可以访问响应式数据和非响应式数据。
缺点:性能开销较大,每次组件重新渲染时都会执行回调函数。
3. 渲染watcher
语法糖:renderWatch
。一个特殊的Watch,专门用于监听组件的渲染函数。
优点:可以访问组件的渲染函数,方便性能优化。
缺点:只能用于组件的渲染函数。
应用场景:量体裁衣
Computed和Watch各有千秋,适用于不同的场景:
使用Computed: 当需要一个依赖于其他属性的值的计算属性时。
使用Watch: 当需要监听某个属性或表达式的变化时。
深入解读:源码探秘
为了更深入地理解Computed和Watch,让我们深入Vue.js的源码一探究竟。
Computed:
export function computed(getterOrOptions, context) {
// 解析 getterOrOptions
let getter;
let setter;
if (typeof getterOrOptions === 'function') {
getter = getterOrOptions;
} else {
// getter 和 setter 函数
getter = getterOrOptions.get || function () {};
setter = getterOrOptions.set || function () {};
}
// 创建依赖追踪器
const watcher = new Watcher(
context,
getter,
undefined, // computed 不支持 setter
{ lazy: true } // computed 默认惰性求值
);
// getter 依赖的属性发生变化时,会触发 watcher
// 进而更新 computed 的值
return {
get() {
// 获取 computed 的值
// 如果是惰性求值,则首次获取时计算
if (watcher.dirty) {
watcher.evaluate();
}
if (Dep.target) {
// 如果有订阅者(比如模板),则收集依赖
watcher.depend();
}
return watcher.value;
},
set(newValue) {
// 理论上 computed 应该是只读的,但还是提供了 setter
// 可以用于手动更新 computed 的值
setter.call(context, newValue);
watcher.evaluate();
}
};
}
Watch:
export function watch(expOrFn, callback, options) {
const watcher = new Watcher(
this,
expOrFn, // 表达式或函数
callback, // 回调函数
options // 选项
);
// 添加到组件的 watcher 数组中
if (this._watchers.length === 0) {
this._isVue = true;
}
this._watchers.push(watcher);
}
性能优化:巧用利器
Computed和Watch都可以用于性能优化:
Computed: 减少不必要的重新渲染。
Watch: 避免不必要的回调函数执行。
结束语:登峰造极
Computed和Watch是Vue.js响应式编程的基石。理解它们的本质区别和应用场景至关重要。掌握了这些利器,你将能够轻松编写出响应迅速、性能卓越的Vue.js应用。
常见问题解答
Q:Computed和Watch哪个性能更好?
A:Computed通常性能更好,因为它只在依赖项发生变化时才会重新计算。
Q:什么时候应该使用Watch,而不是Computed?
A:当需要监听某个属性或表达式的变化,并且该变化不影响组件渲染时,可以使用Watch。
Q:Computed可以访问非响应式数据吗?
A:不可以,Computed只能访问响应式数据。
Q:Watch可以触发重新渲染吗?
A:可以,如果Watch的回调函数修改了响应式数据,就会触发重新渲染。
Q:如何优化Watch的性能?
A:可以使用immediate
选项来避免在初始化时触发回调函数,还可以使用deep
选项来避免深度观察数组和对象。