vue2的响应式思想-依赖收集系统

  • Post author:
  • Post category:vue




响应式系统Vue2实现-依赖收集系统

class Dep {
	constructor() {
		this.subscribers = new Set();
	}
	depend() {
		if (actineEffect) {
			this.subscribers.add(actineEffect)
		}
	}

	notify() {
		this.subscribers.forEach(effect => {
			effect();
		})
	}
}

let actineEffect = null;

function watchEffect(effect) {
	actineEffect = effect;
	effect();
	actineEffect = null;
}

// Map({key:value}):key是一个字符串;
// WeakMap({key(对象):vlaue}):key是一个对象,弱引用
const targetMap = new WeakMap();
function getDep(target, key) {
	// 1、根据对象(taeget)取出对应的Map对象
	let depsMap = targetMap.get(target);
	if (!depsMap) {
		depsMap = new Map();
		targetMap.set(target, depsMap)
	}
	// 2、取出具体的dep对象;
	let dep = depsMap.get(key);
	if (!dep) {
		dep = new Dep();
		depsMap.set(key, dep);
	}
	return dep
}

// vue2对raw进行数据劫持
function reactive(raw) {
	Object.keys(raw).forEach(key => {

		const dep = getDep(raw, key);
		let value = raw[key];

		Object.defineProperty(raw, key, {
			// 获取数据钓鱼用get
			get() {
				dep.depend();
				return value;
			},
			// 设置数据用set
			set(newValue) {
				if (value !== newValue) {
					value = newValue;
					dep.notify();
				}
				
			}
		})
	})
	return raw
}


/* 测试代码 */

const info = reactive({
	counter: 100,
	name: 'pei'
});
const foo = reactive({
	height: 1.63
})
// watchEffect1
watchEffect(function() {
	console.log("打印1", info.counter * 2)
})
// watchEffect2
watchEffect(function() {
	console.log("打印2", info.counter * info.counter)
})
// watchEffect3
watchEffect(function() {
	console.log("打印3", info.counter + 10, info.name)
})
// watchEffect4
watchEffect(function() {
	console.log("打印4", foo.height)
})

info.counter++;



版权声明:本文为peijiajing原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。