《vue设计与实现》第四章 分支切换与 cleanup

1.《vue设计与实现》第四章 分支切换与 cleanup

在上一章节中,我们实现的响应式系统还存在一个问题
那就是在三元运算符中

document.body.innerHTML = obj.ok ? obj.name:'是没有的';

一开始 obj.ok 的初始值为 true, 回导致副作用函数执行时,会有obj.ok, obj.name 两个属性的读取操作。
在这里插入图片描述

但是当我们将 obj.ok 的值修改为 false时,会重新触发副作用函数

document.body.innerHTML = obj.ok ? obj.name : '是没有的';

因为obj.ok的值为 false,所以是不会有读取 obj.name操作的。
意思就是,往后接下来 obj.name修改了,是不会也不需要触发副作用函数的执行,
但是按照上一章的代码实现,是不同实现这个功能的。

总结

  1. 当obj.ok的值由 true, 改为 false,触发了副作用函数执行。
  2. 但是由于没有对obj.name进行读取操作,是不需要对obj.name进行依赖收集的。
  3. 所以往后修改obj.name是不需要触发副作用函数的执行的。

该如何解决呢?
4. 我们需要在执行副作用函数时,清空保存了这个副作用函数的集合。
5. 在清空了之后,需要重新建立依赖,但是建立了依赖是不会包含上面的nayang。
在这里插入图片描述

看代码的深蓝色部分,每个副作用函数都有一个deps里面保存了,收集了这个副作用函数的集合。
好,现在看代码实现

function effect(fn) {
	const effectFn = () => {
		activeFffect = effectFn;
		fn();
	}
	effectFn.deps = [];
	effectFn();
	// 这里我们为,副作用函数fn,进行了一层包装。
	// 其二我们为effectFn,也就是副作用函数添加了一个属性deps, 值为 [] 一个数组
}

其二,在get()中

let obj = new Proxy(data, {
	get(target, key) {
		if (!activeFffect) return target[key];
		let depsMap = bucket.get(target);
		if (!depsMap) {
			bucket.set(target, (depsMap = new Map()))
		}
		let deps = depsMap.get(key);
		if (!deps) {
			depsMap.set(key, (deps = new Set()));
		}
		deps.add(activeFffect);
		activeFffect.deps.push(deps);
		return target[key];
	}
})

新增的代码

activeFffect.deps.push(deps); // 往里面添加收集的集合

接下来看如何清空保存了这个副作用函数的集合
注意我们是要在副作用函数执行之前进行清空操作。
因为当副作用函数执行了,会触发obj.ok读取操作,就会进行依赖收集操作。所以要先清空,在收集

2.cleanup函数

function cleanup(fn) {
	// fn,就是当前要执行的副作用函数
	fn && fn.deps.forEach(item => {
		// 此时的 item 是 new Set();
		item.delete(fn); // 将他从集合中删除掉
	})
	fn.deps.length = 0; // 然后清空这个数组
}

执行了,这一步,关系图就会成为。
在这里插入图片描述
然后再执行副作用函数

document.body.innerHTML = obj.ok ? obj.name : '是没有的';

因为obj.ok的值为false,所以是不会读取到obj.name;
所以只会收集obj.ok属性对应当前的副作用函数。
在这里插入图片描述
此时依赖关系就会变成这样。
上面的函数2,是多画的
往后在去修改obj.name,但是 new Set()集合中是为空的。所以是不会再有任何执行的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值