基础API
ref 函数
使用
实现
先打印出来看它有什么东西,暂不探讨值是对象的情况(会在下一章讲reactive的时候一起讲)
const test = ref('a')
console.log(test);
这可以得出一个结论吧?我们自己可以写一个大概实现如下:
class RefImpl {
constructor(value) {
this.dep = new Set(); // 用于收集依赖
this._v_isRef = true; // 用于判断是否是ref,isRef函数就是利用这个实现的
this._v_isShallow = null; // 用于判断是ref还是shawllowRef
this._rawValue = value; // 存放原始值
this._value = value; // 存放代理值
this.value = value; // value做数据劫持
}
}
ref是如何做到响应式的?
ref在处理基本值的时候用的还是改写属性get和set方法的方式,并没有用proxy
tips:reactive的响应式就是利用proxy实现的,ref处理值为对象的情况底层也是调用reactive,这个后面讲...先上代码看ref如何处理基本值:
class RefImpl {
constructor(value) {
this.dep = new Set();
this._v_isRef = true;
this._v_isShallow = null;
this._rawValue = value
this._value = convert(value); // 判断是否是基本值是的话调用reactive处理
}
get value() {
// 收集依赖, dep.add(依赖)
trackRefValue(this);
return this._value;
}
set value(newValue) {
// 当新的值不等于老的值的话,
// 那么才需要触发依赖
if (hasChanged(newValue, this._rawValue)) {
// 更新值
this._value = convert(newValue);
this._rawValue = newValue;
// 触发依赖 for(const effect of dep) { effect.run() }
triggerRefValue(this);
}
}
}
总结
其实很难把一个api单独提出来讲,因为相关联的东西太多,只能讲它最表面的东西,如果沿着它的函数调用讲下去其实基本要讲完整一个vue3的响应式原理,这篇文章我希望是让大家对ref有一个最基本的认知吧 2022.5.19 00:42 上海浦东