什么是__ob__
对象?
在Vue.js中,每个响应式数据对象都会被转换成一个__ob__
对象。这个对象是一个Observer的实例,负责监听数据的变化并通知依赖的视图组件。__ob__
对象是Vue响应式系统的核心,它确保了当数据发生变化时,视图能够相应地更新。
__ob__
对象的工作原理
1. 数据劫持
Vue.js使用数据劫持技术来监听数据的变化。在Vue 2中,主要是通过Object.defineProperty
来拦截对象的getter和setter操作。当尝试访问或修改对象属性时,Vue会触发getter或setter,从而有机会去收集依赖或触发更新。
function defineReactive(data, key, val) {
let dep = new Dep();
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function() {
dep.depend();
return val;
},
set: function(newVal) {
if (val !== newVal) {
val = newVal;
dep.notify();
}
}
});
}
2. 依赖收集
当访问响应式数据时,__ob__
对象会通过Dep
(依赖)对象来收集依赖。这意味着当组件渲染时,它会订阅数据对象中特定属性的变化。
class Dep {
constructor() {
this.subscribers = [];
}
depend() {
if (typeof window !== 'undefined' && window.target) {
this.subscribers.push(window.target);
}
}
notify() {
this.subscribers.forEach(watcher => watcher.update());
}
}
3. 变化通知
当响应式数据发生变化时,__ob__
对象会通过Dep
对象的notify
方法来通知所有订阅了该数据的watcher对象。watcher对象随后会触发视图的更新。
__ob__
对象在Vue 3中的改进
在Vue 3中,__ob__
对象被替换为一个名为Proxy
的新机制。Proxy
提供了更强大的功能,如可以监听数组索引的变化和对象属性的新增删除。
function reactive(target) {
return new Proxy(target, {
get(target, key, receiver) {
const result = Reflect.get(target, key, receiver);
track(target, key);
return result;
},
set(target, key, value, receiver) {
const oldValue = target[key];
const result = Reflect.set(target, key, value, receiver);
trigger(target, key, value, oldValue);
return result;
}
});
}
function track(target, key) {
if (activeEffect) {
trackEffect(target, key);
}
}
function trigger(target, key, value, oldValue) {
effect();
}
总结
__ob__
对象是Vue.js响应式系统的核心,它通过数据劫持、依赖收集和变化通知来确保数据变化能够实时反映到视图上。了解__ob__
对象的工作原理对于深入理解Vue.js的响应式系统至关重要。随着Vue 3的发布,__ob__
对象被Proxy
所取代,带来了更高效和强大的响应式机制。