淘宝开放平台怎么做淘宝客网站,网站开发 知识产权,怎样做网站公司的销售,网站怎么做分页前言
我们先顺一下vue使用响应式数据的流程#xff1a; vue 是通过 ref 和 reactive 来创建响应式值#xff0c;改变响应式值#xff0c;视图跟着发生变化。 我们今天就来看一下ref和reactive是如何实现的
准备
首先#xff0c;打开ref函数的位置 我们可以看到一个被re…前言
我们先顺一下vue使用响应式数据的流程 vue 是通过 ref 和 reactive 来创建响应式值改变响应式值视图跟着发生变化。 我们今天就来看一下ref和reactive是如何实现的
准备
首先打开ref函数的位置 我们可以看到一个被ref包裹的响应式数据其实是一个RefImpl对象
1. 创建ref
export function ref(value) {return createRef(value);
}function createRef(value) {const refImpl new RefImpl(value);return refImpl;
}可以看到创建一个ref对象的本质就是创建一个RefImpl装饰对象
2. 编写RefImpl对象
export class RefImpl {private _rawValue: any; // 原值private _value: any; // 代理值public dep; // 依赖数组用来存放依赖public __v_isRef true; // 区分是否是ref这个对象类型constructor(value) {this._rawValue value;// 看看value 是不是一个对象如果是一个对象的话// 那么需要用 reactive 包裹一下this._value convert(value);this.dep createDep(); // 创建effect对象}get value() {// 收集依赖trackRefValue(this);return this._value;}set value(newValue) {// 当新的值不等于老的值的话// 那么才需要触发依赖if (hasChanged(newValue, this._rawValue)) {// 更新值this._value convert(newValue);this._rawValue newValue;// 触发依赖triggerRefValue(this);}}
}❤️❤️ 为什么要有_rawValue和_value呢 答_value用来保存我们加工后的具有响应式的对象_rawValue保存的是原始的值 3. 依赖收集和触发
依赖收集
// trackRefValue
export function trackRefValue(ref) {if (isTracking()) { // 判定师傅可以进行收集trackEffects(ref.dep);}
}// trackEffects
let activeEffect void 0;export function trackEffects(dep) {// 用 dep 来存放所有的 effectif (!dep.has(activeEffect)) {dep.add(activeEffect);(activeEffect as any).deps.push(dep);}
}activeEffect作用是用一个全局变量存储被注册的副作用函数
依赖触发 // ref.ts
export function triggerRefValue(ref) {triggerEffects(ref.dep);
}// effect.ts
export function triggerEffects(dep) {// 执行收集到的所有的 effect 的 run 方法for (const effect of dep) {if (effect.scheduler) {// scheduler 可以让用户自己选择调用的时机// 这样就可以灵活的控制调用了// 在 runtime-core 中就是使用了 scheduler 实现了在 next ticker 中调用的逻辑effect.scheduler();} else {effect.run();}}
}
思考
用ref创建的值 .value有什么用