29行代码介绍Vue3响应式及依赖收集
原创
2024-11-27
16:50
编辑于
2024-11-27
16:55
29行代码如下(没算空行)。
<div id="log"></div>
<script>
let activeEffect;
let targetMap = {};
const p = new Proxy(
{ x: 1 },
{
get(target, key, receiver) {
targetMap[key] = activeEffect;
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
Reflect.set(target, key, value, receiver);
if (targetMap[key]) {
targetMap[key]();
}
},
}
);
function effect(fn) {
activeEffect = fn;
fn();
}
effect(() => {
log.innerHTML = p.x;
});
setInterval(function () {
++p.x;
}, 100);
运行效果:
上述代码实现了:p.x的值不断变化,会自动运行用到了p.x的地方,log的内容会自动更新。
上面的代码并非是从Vue3源码中抽取出来,实际Vue3的代码肯定比这复杂一些。但是核心原理是一致的。代码很少也很简单,基本上不用一一说明,这里简单说下几个核心点。
- 基于Proxy去拦截对象属性的赋值及获取,这也是众所周知的Vue3的响应式基础;
- get去做依赖收集,set去做触发依赖,get建立effect和对象的关系,set去找的属性的依赖并执行
- 通过全局变量 activeEffect 建立对象属性和effect直接的关联,上面只用一个对象存了key,实际肯定不能这么简单的去存储依赖关系,源码中是用的 WeakMap,存储了对象、属性、effect的之前的依赖关系(如下图所示)。
转载请注明出处。本文地址:
https://www.qinshenxue.com/article/vue3-reactivity.html
关注我的公众号