ref
export function ref(value?: unknown) {
return createRef(value, false)
}
function createRef(
rawValue: unknown,
shallow: boolean // 用于控制是否进行深层响应式处理 true:不进行,false:进行
) {
// 判断 rawValue 是否为 ref 类型的对象
if (isRef(rawValue)) {
return rawValue
}
return new RefImpl(rawValue, shallow)
}
class RefImpl<T> {
private _value: T // 对原始值的响应式处理
private _rawValue: T // 对原始值的引用
public dep?: Dep = undefined // dep 属性
public readonly __v_isRef = true // 标记,是否为 Ref 对象
constructor(value: T, public readonly __v_isShallow: boolean) {
this._rawValue = __v_isShallow ? value : toRaw(value)
this._value = __v_isShallow ? value : toReactive(value)
}
get value() {
// 收集依赖
trackRefValue(this)
return this._value
}
set value(newVal) {
const useDirectValue =
this.__v_isShallow || isShallow(newVal) || isReadonly(newVal)
newVal = useDirectValue ? newVal : toRaw(newVal)
if (hasChanged(newVal, this._rawValue)) {
this._rawValue = newVal
this._value = useDirectValue ? newVal : toReactive(newVal)
triggerRefValue(this, newVal) // 触发更新以来
}
}
}
当你使用 ref 函数创建一个响应式引用时,Vue3 会调用 createRef 函数,并传入 value 和 false 作为参数,后者表示这是一个普通的 ref。
createRef 函数首先会判断 value 是否已经是一个 ref,如果是,则直接返回 value。否则,会创建一个新的 RefImpl 对象,并将 value 传入其中。
RefImpl 对象会包含 _value 和 _rawValue 两个属性。在构造函数中,会根据 __v_isShallow 的值来判断是否要将传入的 value 变成响应式对象。
当你获取这个响应式引用的值时,Vue3 会调用 get 方法。在 get 方法中,首先会调用 trackRefValue 函数收集这个引用的依赖。
当你设置这个响应式引用的值时,Vue3 会调用 set 方法。在 set 方法中,会判断新值 newVal 是否与旧值 _rawValue 相等。如果不相等,则更新 _rawValue 和 _value,并调用 triggerRefValue 函数触发这个引用的依赖。如果相等,则不进行更新。
今天我找到新工作上班了,所以更新速度可能会慢一点,内容可能会少一点,但绝对不会停下来的,今天就先看看 ref,后面看 reactive 如何对对象响应式处理