导出了什么?
export {
ref,
shallowRef,
isRef,
toRef,
toRefs,
unref,
customRef,
triggerRef,
Ref,
ToRef,
ToRefs,
UnwrapRef,
ShallowUnwrapRef,
RefUnwrapBailTypes
} from './ref'
公共部分
1、创建Ref
function createRef(rawValue: unknown, shallow: boolean) {
if (isRef(rawValue)) {
// 被代理过直接return
return rawValue
}
return new RefImpl(rawValue, shallow)
}
2、创建Ref的类
class RefImpl<T> {
private _value: T
private _rawValue: T
public dep?: Dep = undefined
public readonly __v_isRef = true
constructor(value: T, public readonly _shallow: boolean) {
this._rawValue = _shallow ? value : toRaw(value)
this._value = _shallow ? value : toReactive(value)
}
// toRaw:const raw = observed && (observed as Target)[ReactiveFlags.RAW]
// return raw ? toRaw(raw) : observed
// toReactive:isObject(value) ? reactive(value) : value
// return raw ? toRaw(raw) : observed
get value() {
// 收集依赖
trackRefValue(this)
return this._value
}
set value(newVal) {
newVal = this._shallow ? newVal : toRaw(newVal)
if (hasChanged(newVal, this._rawValue)) {
this._rawValue = newVal
this._value = this._shallow ? newVal : toReactive(newVal)
// 触发依赖
triggerRefValue(this, newVal)
}
}
}
3、type和接口,不细讲了
Ref,
ToRef,
ToRefs,
UnwrapRef,
ShallowUnwrapRef,
RefUnwrapBailTypes
ref
接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象具有指向内部值的单个 property .value
核心
export function ref(value?: unknown) {
return createRef(value, false)
}
细节
- 第二个参数shallow=false
- this._rawValue = toRaw(value) 被代理过:数据还原;未被代理:返回自身 this._value = toReactive(value) 对象:进行代理;原始值:返回自身
- get收集依赖,返回_value
- newVal:被代理过:数据还原;未被代理:返回自身
- hasChanged对比前后数据
- 更新_rawValue、_value,触发依赖
constructor(value: T, public readonly _shallow: boolean) {
this._rawValue = _shallow ? value : toRaw(value)
this._value = _shallow ? value : toReactive(value)
}
get value() {
trackRefValue(this)
return this._value
}
set value(newVal) {
newVal = this._shallow ? newVal : toRaw(newVal)
if (hasChanged(newVal, this._rawValue)) {
this._rawValue = newVal
this._value = this._shallow ? newVal : toReactive(newVal)
triggerRefValue(this, newVal)
}
}
shallowRef
创建一个跟踪自身 .value 变化的 ref,但不会使其值也变成响应式的。
核心
function shallowRef(value) {
return createRef(value, true)
}
细节
- 第二个参数shallow=true
- this._rawValue = value this._value = value
- get收集依赖,返回_value
- hasChanged对比前后数据
- 更新_rawValue、_value,触发依赖
constructor(value: T, public readonly _shallow: boolean) {
this._rawValue = _shallow ? value : toRaw(value)
this._value = _shallow ? value : toReactive(value)
}
get value() {
trackRefValue(this)
return this._value
}
set value(newVal) {
newVal = this._shallow ? newVal : toRaw(newVal)
if (hasChanged(newVal, this._rawValue)) {
this._rawValue = newVal
this._value = this._shallow ? newVal : toReactive(newVal)
triggerRefValue(this, newVal)
}
}
ref和shallowRef区别
- ref:this._rawValue存储数据本身,this._value存储被代理后的数据
- shallowRef:this._rawValue、this._value都存储数据本身
参数
- 原始值:.value获取的都是数据本身,没有区别;
- 引用值:ref的.value返回代理后的数据,shallowRef的.value返回数据本身
isRef
检查值是否为一个 ref 对象。
核心
公共部分2第6行代码,被ref过的数据会有__v_isRef=true
function isRef(r) {
return Boolean(r && r.__v_isRef === true)
}
toRef
可以用来为源响应式对象上的某个 property 新创建一个 ref。然后,ref 可以被传递,它会保持对其源 property 的响应式连接。
核心
把ref和对象的一个属性进行链接
function toRef(object, key) {
const val = object[key]
return isRef(val) ? val : new ObjectRefImpl(object, key)
}
class ObjectRefImpl<T extends object, K extends keyof T> {
public readonly __v_isRef = true
constructor(private readonly _object: T, private readonly _key: K) {}
get value() {
return this._object[this._key]
}
set value(newVal) {
this._object[this._key] = newVal
}
}
toRefs
将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的 ref。
核心
- 参数必须是被代理过的,否则回报错
- 构建对象或数组,把每一项进行toRef
function toRefs(object) {
if (__DEV__ && !isProxy(object)) {
console.warn(`toRefs() expects a reactive object but received a plain one.`)
}
const ret = isArray(object) ? new Array(object.length) : {}
for (const key in object) {
ret[key] = toRef(object, key)
}
return ret
}
unref
如果参数是一个 ref,则返回内部值,否则返回参数本身。这是 val = isRef(val) ? val.value : val 的语法糖函数。
核心
是ref就return它的value
function unref(ref) {
return isRef(ref) ? ref.value : ref
}
customRef
创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track 和 trigger 函数作为参数,并且应该返回一个带有 get 和 set 的对象。
核心
自定义Ref的get、set
function customRef(factory) {
return new CustomRefImpl(factory)
}
class CustomRefImpl<T> {
public dep?: Dep = undefined
private readonly _get: ReturnType<CustomRefFactory<T>>['get']
private readonly _set: ReturnType<CustomRefFactory<T>>['set']
public readonly __v_isRef = true
constructor(factory) {
const { get, set } = factory(
() => trackRefValue(this),
() => triggerRefValue(this)
)
this._get = get
this._set = set
}
get value() {
return this._get()
}
set value(newVal) {
this._set(newVal)
}
}
triggerRef
手动执行与 shallowRef 关联的任何作用 (effect)。
例子:shallowRef,参数是对象{greet: 'Hello, world'},执行shallow.value.greet = 'Hello, universe',不会触发依赖,调用triggerRef(ref),就能触发依赖
核心
触发一次依赖
function triggerRef(ref: Ref) {
triggerRefValue(ref, __DEV__ ? ref.value : void 0)
}
function triggerRefValue(ref, newVal) {
ref = toRaw(ref)
if (ref.dep) {
if (__DEV__) {
triggerEffects(ref.dep, {
target: ref,
type: TriggerOpTypes.SET,
key: 'value',
newValue: newVal
})
} else {
triggerEffects(ref.dep)
}
}
}