[Vue]响应式机制自实现

响应式机制

在Vue文档的深入响应式机制中,提到Vue基于ES5的Object.defineProperty实现了其响应机制,并给出了它的逻辑结构图。

理论上,每一个Vue组件实例拥有一个Watcher实例,其逻辑图为:
[Vue]响应式机制自实现_第1张图片

挺有意思的,在看源码前,自己照着个图实现了一下。

Watcher

class Watcher{
	constructor(el){
		this.el = el;
		this.data = undefined;
		this.dependency = undefined;
	}
	setData(data,dependency){
		this.data = data;
		this.dependency = dependency;
		this.bind();
		this.init();
	}
	bind(){
		let self = this;
		Object.keys(self.data).forEach(key => {
			let value = self.data[key];
			const dm = new DepManager();
			dm.register(self);
			Object.defineProperty(self.data, key, {
				get(){
					for(let dep of self.dependency){
						dm.collect(dep);
					}
					return value;
				},
				set(newValue){
					value = newValue;
					dm.notify();
				}
			});
		});
	}
	// 初始化界面渲染效果
	init(){
		let self = this;
		for(let dep of self.dependency){
			this.render(dep)
		}
	}
	// 渲染函数
	render(func){
		// 相应的渲染方法
		document.getElementById(this.el).innerHTML=func();
	}
}

依赖管理

// 依赖管理者
class DepManager{
	constructor(){
		// 依赖的方法
		this.dependency = [];
		// 该属性的相关依赖的订阅者
		this.subscribers = [];
	}
	// 注册订阅者
	register(sub){
		if(!this.subscribers.includes(sub))
			this.subscribers.push(sub);
	}
	// 收集依赖
	collect(dependency){
		if(!this.dependency.includes(dependency))
			this.dependency.push(dependency);
	}
	// 通知更新
	notify(){
		let self = this;
		this.dependency.forEach( dep => {
			self.subscribers.forEach( sub => sub.render(dep));
		});
	}
};

实例化

var data = { a:2, b:3 };
var me = new Watcher('test'); // 绑定
me.setData(data,[()=>data.a*data.b])

效果演示

[Vue]响应式机制自实现_第2张图片

你可能感兴趣的:([Vue]响应式机制自实现)