响应性基础API
graph TD
A[reactive]
B[readonly]
C[shallowReactive]
D[shallowReadonly]
E[createReactiveObject]
F(proxy)
A-->E
B-->E
C-->E
D-->E
E-->F
reactive
返回对象的响应式副本
export function reactive(target: object) {
if (target && (target as Target)[ReactiveFlags.IS_READONLY]) {
return target
}
return createReactiveObject(
target,
false,
mutableHandlers,
mutableCollectionHandlers,
reactiveMap
)
}
readonly
接受一个对象 (响应式或纯对象) 或 ref 并返回原始对象的只读代理。
export function readonly<T extends object>(
target: T
): DeepReadonly<UnwrapNestedRefs<T>> {
return createReactiveObject(
target,
true,
readonlyHandlers,
readonlyCollectionHandlers,
readonlyMap
)
}
isProxy
检查对象是否是由 reactive 或 readonly 创建的 proxy。返回布尔值。
export function isProxy(value: unknown): boolean {
return isReactive(value) || isReadonly(value)
}
isReactive
检查对象是否是由 reactive 创建的响应式代理。返回布尔值。
export function isReactive(value: unknown): boolean {
if (isReadonly(value)) {
return isReactive((value as Target)[ReactiveFlags.RAW])
}
return !!(value && (value as Target)[ReactiveFlags.IS_REACTIVE])
}
isReadonly
检查对象是否是由 readonly 创建的只读代理。返回布尔值。
export function isReadonly(value: unknown): boolean {
return !!(value && (value as Target)[ReactiveFlags.IS_READONLY])
}
toRaw
返回 reactive 或 readonly 代理的原始对象。
export function toRaw<T>(observed: T): T {
return (
(observed && toRaw((observed as Target)[ReactiveFlags.RAW])) || observed
)
}
markRaw
标记一个对象,使其永远不会转换为 proxy。返回对象本身。
export function markRaw<T extends object>(value: T): T {
def(value, ReactiveFlags.SKIP, true)
return value
}
shallowReactive
创建一个响应式代理,它跟踪其自身 property 的响应性,但不执行嵌套对象的深层响应式转换 (暴露原始值)。
export function shallowReactive<T extends object>(target: T): T {
return createReactiveObject(
target,
false,
shallowReactiveHandlers,
shallowCollectionHandlers,
shallowReactiveMap
)
}
shallowReadonly
创建一个 proxy,使其自身的 property 为只读,但不执行嵌套对象的深度只读转换 (暴露原始值)。
export function shallowReadonly<T extends object>(
target: T
): Readonly<{ [K in keyof T]: UnwrapNestedRefs<T[K]> }> {
return createReactiveObject(
target,
true,
shallowReadonlyHandlers,
shallowReadonlyCollectionHandlers,
shallowReadonlyMap
)
}
Refs
-
ref
接受一个内部值并返回一个响应式且可变的 ref 对象。
-
unref
如果参数是一个 ref,则返回内部值,否则返回参数本身。
-
toRef
可以用来为源响应式对象上的某个 property 新创建一个 ref。然后,ref 可以被传递,它会保持对其源 property 的响应式连接。
-
toRefs
将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的 ref。
-
isRef
检查值是否为一个 ref 对象。
-
customRef
创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。
-
shallowRef
创建一个跟踪自身 .value 变化的 ref,但不会使其值也变成响应式的。
-
triggerRef
手动执行与 shallowRef 关联的任何副作用。
computed
- 接受一个 getter 函数,并为从 getter 返回的值返回一个不变的响应式 ref 对象。
- 或者,它也可以使用具有 get 和 set 函数的对象来创建可写的 ref 对象。
export function computed<T>(
getterOrOptions: ComputedGetter<T> | WritableComputedOptions<T>
) {
let getter: ComputedGetter<T>
let setter: ComputedSetter<T>
if (isFunction(getterOrOptions)) {
getter = getterOrOptions
setter = __DEV__
? () => {
console.warn('Write operation failed: computed value is readonly')
}
: NOOP
} else {
getter = getterOrOptions.get
setter = getterOrOptions.set
}
return new ComputedRefImpl(
getter,
setter,
isFunction(getterOrOptions) || !getterOrOptions.set
) as any
}
class ComputedRefImpl<T> {
private _value!: T
private _dirty = true
public readonly effect: ReactiveEffect<T>
public readonly __v_isRef = true;
public readonly [ReactiveFlags.IS_READONLY]: boolean
constructor(
getter: ComputedGetter<T>,
private readonly _setter: ComputedSetter<T>,
isReadonly: boolean
) {
this.effect = effect(getter, {
lazy: true,
scheduler: () => {
if (!this._dirty) {
this._dirty = true
trigger(toRaw(this), TriggerOpTypes.SET, 'value')
}
}
})
this[ReactiveFlags.IS_READONLY] = isReadonly
}
get value() {
const self = toRaw(this)
if (self._dirty) {
self._value = this.effect()
self._dirty = false
}
track(self, TrackOpTypes.GET, 'value')
return self._value
}
set value(newValue: T) {
this._setter(newValue)
}
}
watchEffect
- 在响应式地跟踪其依赖项时立即运行一个函数,并在更改依赖项时重新运行它。
watch
- watch 需要侦听特定的数据源,并在单独的回调函数中执行副作用。默认情况下,它也是惰性的——即回调仅在侦听源发生更改时被调用。
- 与 watchEffect 比较,watch 允许我们:
- 惰性地执行副作用;
- 更具体地说明应触发侦听器重新运行的状态;
- 访问被侦听状态的先前值和当前值