// 生成vue的响应式原理
function defineReactive(obj, key, val) {
// 递归
observe(val);
// 创建Dep实例
const dep = new Dep();
Object.defineProperty(obj, key, {
get() {
// 收集依赖
Dep.target && dep.addDep(Dep.target);
return val;
},
set(newVal) {
if (newVal !== val) {
// 递归
observe(newVal);
val = newVal;
// 发送通知
dep.notify();
}
},
});
}
// 生成vue响应式的observe函数
function observe(obj) {
if (typeof obj !== "object" || obj === null) {
return;
}
new Observer(obj);
}
// 生成vue响应式的Observer类
class Observer {
constructor(value) {
this.value = value;
// 判断value的类型
if (Array.isArray(value)) {
// todo
} else {
this.walk(value);
}
}
// 遍历对象的每一个key,对每一个key调用defineReactive
walk(obj) {
Object.keys(obj).forEach((key) => {
defineReactive(obj, key, obj[key]);
});
}
}
// 生成vue响应式的Dep类,用来收集依赖和发送通知
// 定义一个全局的target属性,用来存储当前的watcher
// Dep.target是一个全局的唯一的watcher,因此在使用的时候需要先保存之前的值,使用完之后再恢复
class Dep {
static target = '';
constructor() {
this.deps = [];
}
addDep(dep) {
this.deps.push(dep);
}
notify() {
// 何时调用notify => 在属性的setter函数中调用
this.deps.forEach((dep) => dep.update());
}
}
// Dep.target在何时赋值 => 在Watcher的get方法中赋值
// 生成vue响应式的Watcher类,用来收集依赖和发送通知
// watcher是什么 => watcher是一个类,用来实例化一个watcher对象
// watcher有什么作用 => watcher的作用是在数据发生变化的时候,执行对应的更新函数
// watcher有哪些属性 => watcher有getter、options两个属性
// watcher有哪些方法 => watcher有get、update两个方法
// watcher对于的中文名称是什么 => watcher对应的中文名称是观察者
class Watcher {
constructor(getter, options) {
// getter是一个函数,函数中调用了data中的属性,从而触发属性的getter函数
this.getter = getter;
// options是一个对象,包含了watcher的一些配置,例如:immediate、deep、lazy等
this.options = options;
this.get();
}
get() {
// 将Dep.target指向当前的Watcher实例
// @ts-ignore
Dep.target = this;
// 执行getter函数,触发属性的getter函数
this.getter();
// 将Dep.target置为null
// @ts-ignore
Dep.target = null;
}
update() {
// 具体的更新逻辑
this.get();
}
}
// watcher在何时创建 => 在组件的mounted钩子函数中创建
// 在mounted中如何创建watcher => 通过调用render函数来创建watcher
// render函数在何时调用 => 在组件的render函数中调用 => new Watcher(getter, options)
// getter是一个函数,函数中调用了data中的属性,从而触发属性的getter函数
标签:vue,obj,target,Dep,watcher,响应,getter,copilot,函数
From: https://www.cnblogs.com/crispyChicken/p/17262260.html