Vue2和Vue3的响应式原理
Posted 还是不会呀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue2和Vue3的响应式原理相关的知识,希望对你有一定的参考价值。
Vue2和Vue3的响应式原理
这个其实在Vue2&Vue3专栏的源码学习部分,已经实现过,但是当时还是对部分的数据结构存在不明确的部分,比如说Proxy类,Reflect对象,Set数据结构,就没有运用这部分知识点,用了也不明确。那么这篇文章,可以在之前实现得基础上做出优化,利用ES6的新知识点
依赖保存的数据结构
vue3实现原理
let activeFn = null;
class Depend {
constructor() {
this.depend = new Set();
}
addDep() {
if (activeFn) {
this.depend.add(activeFn);
}
}
notify() {
this.depend.forEach((fn) => {
fn();
});
}
}
function watchFn(fn) {
activeFn = fn;
fn();
activeFn = null;
}
let weakMap = new WeakMap();
function getDep(raw, key) {
let dep = weakMap.get(raw);
if (!dep) {
dep = new Map();
weakMap.set(raw, dep);
}
let deep = dep.get(key);
if (!deep) {
deep = new Depend();
dep.set(key, deep);
}
return deep;
}
function reactive(raw) {
return new Proxy(raw, {
get(target, key, receiver) {
const deep = getDep(target, key);
deep.addDep();
return Reflect.get(target, key, receiver);
},
set(target, key, newValue, receiver) {
Reflect.set(target, key, newValue, receiver);
const deep = getDep(target, key);
deep.notify();
},
});
}
// 测试代码
const info = reactive({
name: "fzb",
age: 21,
});
watchFn(function () {
console.log(info.name, "----------------1");
});
watchFn(function () {
console.log(info.name, "----------------2");
});
watchFn(function () {
console.log(info.age, "----------------1");
});
info.name = "gj";
info.age++;
vue2实现原理
let activeFn = null;
class Depend {
constructor() {
this.depend = new Set();
}
addDep() {
if (activeFn) {
this.depend.add(activeFn);
}
}
notify() {
this.depend.forEach((fn) => {
fn();
});
}
}
function watchFn(fn) {
activeFn = fn;
fn();
activeFn = null;
}
let weakMap = new WeakMap();
function getDep(raw, key) {
let dep = weakMap.get(raw);
if (!dep) {
dep = new Map();
weakMap.set(raw, dep);
}
let deep = dep.get(key);
if (!deep) {
deep = new Depend();
dep.set(key, deep);
}
return deep;
}
function reactive(raw) {
Object.keys(raw).forEach((key) => {
let value = raw[key];
let deep = getDep(raw, key);
Object.defineProperty(raw, key, {
get() {
deep.addDep();
return value;
},
set(newValue) {
value = newValue;
deep.notify();
},
});
});
return raw;
}
// 测试代码
const info = reactive({
name: "fzb",
age: 21,
});
watchFn(function () {
console.log(info.name, "----------------1");
});
watchFn(function () {
console.log(info.name, "----------------2");
});
watchFn(function () {
console.log(info.age, "----------------1");
});
info.name = "gj";
info.age++;
以上是关于Vue2和Vue3的响应式原理的主要内容,如果未能解决你的问题,请参考以下文章
vue2的响应式原理学“废”了吗?继续观摩vue3响应式原理Proxy
Vue3官网-高级指南(十七)响应式计算`computed`和侦听`watchEffect`(onTrackonTriggeronInvalidate副作用的刷新时机`watch` pre)(代码片段