class Depend {
constructor() {
//set不允许重复
this.reactiveFns = new Set();
}
//添加对应的依赖
addDepend(fn) {
if (fn) {
this.reactiveFns.add(fn);
}
}
depend() {
if (reactiveFn) {
this.reactiveFns.add(reactiveFn);
}
}
//通知数据发生变化,收集依赖
notify() {
this.reactiveFns.forEach((fn) => {
fn();
});
}
}
//定义一个函数,专门执行响应式函数
//形成闭包
let reactiveFn = null;
function watchFn(fn) {
//一旦执行函数,将值赋值给reactiveFn
reactiveFn = fn;
fn();
//函数保存起来,默认执行一次
//类似于wachEeffct(),自动收集依赖,立即执行执行一次
reactiveFn = null;
//执行完操作之后,赋值为空,有可能对后续操作造成影响
}
//封装一个函数,来获取对应的depend对象
//利用weakMap,弱引用,即使obj为null,也不能对后续造成影响,
const objMap = new WeakMap();
function getDepend(obj, key) {
//根据对象obj,找到对应的map对象
let map = objMap.get(obj);
if (!map) {
//weakMap的key必须要是对象,所以这里用Map()
//如果拿不到,我们就new一个
map = new Map();
objMap.set(obj, map);
}
//根据key,找到对应的depend对象
let dep = map.get(key);
if (!dep) {
dep = new Depend();
map.set(key, dep);
}
//所以一定可以返回拿到一个dep对象
return dep;
}
//方案一。Object.defineProperty() -> Vue2
//对obj里面的数据进行遍历
function reactive(obj) {
Object.keys(obj).forEach((key) => {
let value = obj[key];
//对每个key和set操作进行对应劫持
Object.defineProperty(obj, key, {
set: function (newValue) {
//保存value值
value = newValue;
const dep = getDepend(obj, key);
//去通知更新
dep.notify();
},
get: function () {
// 拿到obj -> key
// 找到对应的obj对象的key对应的dep对象
const dep = getDepend(obj, key);
//间接的把函数添加进去
dep.depend();
return value;
},
});
});
return obj;
}
//----------------------
const obj = reactive({
name: "james",
age: 38,
});
//凡是传进watchFn函数里面就是响应式的
watchFn(function foo() {
console.log("foo name is", obj.name);
console.log("foo age is ", obj.age);
console.log("foo age is ", obj.age);
});
const user = reactive({
height: 188,
name: "peter",
});
watchFn(function bar() {
console.log("user height", user.height);
console.log("user name", user.name);
});
console.log("监听obj-age发生变化~~~~~~~~");
obj.age += 100;
console.log("监听name发生变化~~~~~~~~");
user.name += "123";
手写vue2响应式原理最终代码
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
推荐阅读更多精彩内容
- 1、 数据响应式 首先请大家认真的思考一个问题:什么是数据响应式? 答:数据变化是可侦测的,并且和数据相关的内容可...
- 本文源码版本 Vue3.2.11,Vue2 响应式源码剖析点这里 深入浅出 Vue2 响应式原理源码剖析[http...