源码仓库
https://github.com/vuejs/core/tree/v3.2.37
reactivity响应式系统源码位置
packages/reactivity
主入口文件
packages/reactivity/src/index.ts
export {
ref, // 创建一个响应式引用
shallowRef, // 创建一个浅层响应式引用
isRef, // 检查一个值是否是响应式引用
toRef, // 将一个响应式对象的属性转换为响应式引用
toRefs, // 将一个响应式对象的所有属性转换为响应式引用
unref, // 获取响应式引用的值
proxyRefs, // 代理响应式引用,使其可以直接访问值
customRef, // 创建自定义的响应式引用
triggerRef, // 触发响应式引用的更新
Ref, // 响应式引用的类型
ToRef, // toRef函数的返回类型
ToRefs, // toRefs函数的返回类型
UnwrapRef, // 解包响应式引用的类型
ShallowRef, // 浅层响应式引用的类型
ShallowUnwrapRef, // 解包浅层响应式引用的类型
RefUnwrapBailTypes, // 解包响应式引用时需要跳过的类型
CustomRefFactory // 自定义响应式引用工厂的类型
} from './ref'
// 导出响应式对象相关功能
export {
reactive, // 将一个普通对象转换为响应式对象
readonly, // 将一个普通对象转换为只读的响应式对象
isReactive, // 检查一个对象是否是响应式对象
isReadonly, // 检查一个对象是否是只读的响应式对象
isShallow, // 检查一个对象是否是浅层响应式对象
isProxy, // 检查一个对象是否是代理对象
shallowReactive, // 创建一个浅层响应式对象
shallowReadonly, // 创建一个浅层只读的响应式对象
markRaw, // 标记一个对象为非响应式
toRaw, // 获取一个响应式对象的原始对象
ReactiveFlags, // 响应式对象的特殊标志
DeepReadonly, // 深层只读的响应式对象类型
ShallowReactive, // 浅层响应式对象类型
UnwrapNestedRefs // 解包嵌套响应式引用的类型
} from './reactive'
// 导出计算属性相关功能
export {
computed, // 创建一个计算属性
ComputedRef, // 计算属性的类型
WritableComputedRef, // 可写的计算属性的类型
WritableComputedOptions, // 可写的计算属性的选项
ComputedGetter, // 计算属性的getter函数类型
ComputedSetter // 计算属性的setter函数类型
} from './computed'
// 导出延迟计算属性功能
export { deferredComputed } from './deferredComputed'
// 导出副作用相关功能
export {
effect, // 创建一个副作用函数
stop, // 停止一个副作用函数的自动执行
trigger, // 触发副作用函数的执行
track, // 跟踪副作用函数的依赖
enableTracking, // 启用副作用函数的依赖跟踪
pauseTracking, // 暂停副作用函数的依赖跟踪
resetTracking, // 重置副作用函数的依赖跟踪
ITERATE_KEY, // 迭代操作的特殊键
ReactiveEffect, // 副作用函数的类型
ReactiveEffectRunner, // 副作用函数的执行器类型
ReactiveEffectOptions, // 副作用函数的选项
EffectScheduler, // 副作用函数的调度器类型
DebuggerOptions, // 调试选项
DebuggerEvent, // 调试事件
DebuggerEventExtraInfo // 调试事件的额外信息
} from './effect'
// 导出副作用作用域相关功能
export {
effectScope, // 创建一个副作用作用域
EffectScope, // 副作用作用域的类型
getCurrentScope, // 获取当前的副作用作用域
onScopeDispose // 注册一个在副作用作用域销毁时执行的回调
} from './effectScope'
// 导出操作类型
export { TrackOpTypes, TriggerOpTypes } from './operations'
./reactive
源码:
从./reactive
源码入手,源码如下:
// 引入工具函数和类型
import { isObject, toRawType, def } from '@vue/shared'
import {
mutableHandlers,
readonlyHandlers,
shallowReactiveHandlers,
shallowReadonlyHandlers
} from './baseHandlers'
import {
mutableCollectionHandlers,
readonlyCollectionHandlers,
shallowCollectionHandlers,
shallowReadonlyCollectionHandlers
} from './collectionHandlers'
import type { UnwrapRefSimple, Ref, RawSymbol } from './ref'
// 定义响应式对象的内部标志
export const enum ReactiveFlags {
SKIP = '__v_skip', // 跳过响应式转换的标志
IS_REACTIVE = '__v_isReactive', // 是否是响应式对象
IS_READONLY = '__v_isReadonly', // 是否是只读对象
IS_SHALLOW = '__v_isShallow', // 是否是浅层响应式
RAW = '__v_raw' // 原始对象的引用
}
// 定义响应式对象的类型
export interface Target {
[ReactiveFlags.SKIP]?: boolean
[ReactiveFlags.IS_REACTIVE]?: boolean
[ReactiveFlags.IS_READONLY]?: boolean
[ReactiveFlags.IS_SHALLOW]?: boolean
[ReactiveFlags.RAW]?: any
}
// 定义存储响应式对象的WeakMap
// weakmap只能以对象为键,创建弱引用的map,当没有强引用指向其中的对象后,垃圾处理器将会随时清除其,能有效防止内存泄漏
export const reactiveMap = new WeakMap<Target, any>()
export const shallowReactiveMap = new WeakMap<Target, any>()
export const readonlyMap = new WeakMap<Target, any>()
export const shallowReadonlyMap = new WeakMap<Target, any>()
// 定义目标类型的枚举
const enum TargetType {
INVALID = 0, // 无效类型
COMMON = 1, // 普通对象或数组
COLLECTION = 2 // 集合类型(Map、Set等)
}
// 根据原始类型返回目标类型
function targetTypeMap(rawType: string) {
switch (rawType) {
case 'Object':
case 'Array':
return TargetType.COMMON
case 'Map':
case 'Set':
case 'WeakMap':
case 'WeakSet':
return TargetType.COLLECTION
default:
return TargetType.INVALID
}
}
// 获取目标类型
// 主要目的是判断目标对象是否可以转化为响应式对象
function getTargetType(value: Target) {
return value[ReactiveFlags.SKIP] || !Object.isExtensible(value)
? TargetType.INVALID
: targetTypeMap(toRawType(value))
// 如果响应式对象被标记为SKIP或对象不可扩展(Object.isExtensible检查对象是否可扩展)
// 否则返回TargetType.INVALID否则根据目标对象原始类型返回目标类型
}
// 定义类型,用于解包嵌套的响应式引用
export type UnwrapNestedRefs<T> = T extends Ref ? T : UnwrapRefSimple<T>
// 创建一个响应式对象的函数
export function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
export function reactive(target: object) {
// 如果目标已经是只读的响应式对象,直接返回
if (isReadonly(target)) {
return target
}
// 调用createReactiveObject创建响应式对象
return createReactiveObject(
target,
false,
mutableHandlers,
mutableCollectionHandlers,
reactiveMap
)
}
// 定义浅层响应式的标记
export declare const ShallowReactiveMarker: unique symbol
// 定义浅层响应式的类型
export type ShallowReactive<T> = T & { [ShallowReactiveMarker]?: true }
// 创建一个浅层响应式对象的函数
export function shallowReactive<T extends object>(target: T): ShallowReactive<T> {
return createReactiveObject(
target,
false,
shallowReactiveHandlers,
shallowCollectionHandlers,
shallowReactiveMap
)
}
// 定义深层只读类型的类型
export type DeepReadonly<T> = T extends Builtin
? T
: T extends Map<infer K, infer V>
? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>>
: T extends ReadonlyMap<infer K, infer V>
? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>>
: T extends WeakMap<infer K, infer V>
? WeakMap<DeepReadonly<K>, DeepReadonly<V>>
: T extends Set<infer U>
? ReadonlySet<DeepReadonly<U>>
: T extends ReadonlySet<infer U>
? ReadonlySet<DeepReadonly<U>>
: T extends WeakSet<infer U>
? WeakSet<DeepReadonly<U>>
: T extends Promise<infer U>
? Promise<DeepReadonly<U>>
: T extends Ref<infer U>
? Readonly<Ref<DeepReadonly<U>>>
: T extends {}
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
: Readonly<T>
// 创建一个只读响应式对象的函数
export function readonly<T extends object>(target: T): DeepReadonly<UnwrapNestedRefs<T>> {
return createReactiveObject(
target,
true,
readonlyHandlers,
readonlyCollectionHandlers,
readonlyMap
)
}
// 创建一个浅层只读响应式对象的函数
export function shallowReadonly<T extends object>(target: T): Readonly<T> {
return createReactiveObject(
target,
true,
shallowReadonlyHandlers,
shallowReadonlyCollectionHandlers,
shallowReadonlyMap
)
}
// 创建响应式对象的通用函数
function createReactiveObject(
target: Target,
isReadonly: boolean,
baseHandlers: ProxyHandler<any>,
collectionHandlers: ProxyHandler<any>,
proxyMap: WeakMap<Target, any>
) {
// 如果目标不是对象,直接返回
if (!isObject(target)) {
if (__DEV__) {
console.warn(`value cannot be made reactive: ${String(target)}`)
}
return target
}
// 如果目标已经是代理对象,直接返回
if (
target[ReactiveFlags.RAW] &&
!(isReadonly && target[ReactiveFlags.IS_REACTIVE])
) {
return target
}
// 如果目标已经有对应的代理对象,直接返回
const existingProxy = proxyMap.get(target)
if (existingProxy) {
return existingProxy
}
// 只有特定的值类型可以被观察
const targetType = getTargetType(target)
if (targetType === TargetType.INVALID) {
return target
}
// 创建代理对象
const proxy = new Proxy(
target,
targetType === TargetType.COLLECTION ? collectionHandlers : baseHandlers
)
// 将代理对象存储到WeakMap中
proxyMap.set(target, proxy)
return proxy
}
// 检查一个值是否是响应式对象
export function isReactive(value: unknown): boolean {
if (isReadonly(value)) {
return isReactive((value as Target)[ReactiveFlags.RAW])
}
return !!(value && (value as Target)[ReactiveFlags.IS_REACTIVE])
}
// 检查一个值是否是只读响应式对象
export function isReadonly(value: unknown): boolean {
return !!(value && (value as Target)[ReactiveFlags.IS_READONLY])
}
// 检查一个值是否是浅层响应式对象
export function isShallow(value: unknown): boolean {
return !!(value && (value as Target)[ReactiveFlags.IS_SHALLOW])
}
// 检查一个值是否是代理对象
export function isProxy(value: unknown): boolean {
return isReactive(value) || isReadonly(value)
}
// 获取响应式对象的原始对象
export function toRaw<T>(observed: T): T {
const raw = observed && (observed as Target)[ReactiveFlags.RAW]
return raw ? toRaw(raw) : observed
}
// 标记一个对象为非响应式
export function markRaw<T extends object>(value: T): T & { [RawSymbol]?: true } {
def(value, ReactiveFlags.SKIP, true)
return value
}
// 将一个值转换为响应式对象
export const toReactive = <T extends unknown>(value: T): T =>
isObject(value) ? reactive(value) : value
// 将一个值转换为只读响应式对象
export const toReadonly = <T extends unknown>(value: T): T =>
isObject(value) ? readonly(value as Record<any, any>) : value
最主要函数:createReactiveObject
function createReactiveObject( // 传入五个属性,区分创建不同的响应式对象
target: Target, // 目标对象
isReadonly: boolean, //是否只读
baseHandlers: ProxyHandler<any>, // 使用什么处理器函数来处理普通对象
collectionHandlers: ProxyHandler<any>, // 使用什么处理器函数来处理集合对象(map、set)
proxyMap: WeakMap<Target, any> // 将返回的Proxy对象存储在哪一张weakmap表里,用作缓存,有效减少相同响应式对象重复构建
) {
// 如果目标不是对象,直接返回
if (!isObject(target)) {
if (__DEV__) {
console.warn(`value cannot be made reactive: ${String(target)}`)
}
return target
}
// 如果目标已经是响应式对象,直接返回
if (
target[ReactiveFlags.RAW] &&
!(isReadonly && target[ReactiveFlags.IS_REACTIVE])
) {
return target
}
// 如果在相应表里已经有对应的响应式对象,直接返回表中对象
const existingProxy = proxyMap.get(target)
if (existingProxy) {
return existingProxy
}
// 如果是无效类型直接返回
const targetType = getTargetType(target)
if (targetType === TargetType.INVALID) {
return target
}
// 创建代理对象,如果是普通对象,使用baseHandlers,如果是集合对象,使用collectionHandlers
const proxy = new Proxy(
target,
targetType === TargetType.COLLECTION ? collectionHandlers : baseHandlers
)
// 将代理对象存储到相应的WeakMap中
proxyMap.set(target, proxy)
return proxy
}
./ref
源码:
import {
activeEffect, // 当前激活的 effect
shouldTrack, // 是否应该进行依赖收集
trackEffects, // 跟踪依赖
triggerEffects // 触发依赖
} from './effect'
// 导入依赖操作类型
import { TrackOpTypes, TriggerOpTypes } from './operations'
// 导入一些工具函数
import { isArray, hasChanged, IfAny } from '@vue/shared'
// 导入与响应式相关的函数和类型
import { isProxy, toRaw, isReactive, toReactive } from './reactive'
import type { ShallowReactiveMarker } from './reactive'
// 导入集合类型
import { CollectionTypes } from './collectionHandlers'
// 导入依赖类
import { createDep, Dep } from './dep'
// 声明一个唯一的符号,用于标记 Ref 类型
declare const RefSymbol: unique symbol
// 定义 Ref 接口,表示一个响应式引用
export declare const RawSymbol: unique symbol
export interface Ref<T = any> {
value: T // 引用的值
[RefSymbol]: true // 用于标记这是一个 Ref 类型
}
// 定义 RefBase 类型,表示一个基本的引用类型
type RefBase<T> = {
dep?: Dep // 依赖集合
value: T // 引用的值
}
// 跟踪引用值的依赖
export function trackRefValue(ref: RefBase<any>) {
if (shouldTrack && activeEffect) { // 如果应该跟踪且有激活的 effect
ref = toRaw(ref) // 获取原始引用
if (__DEV__) { // 开发模式下
trackEffects(ref.dep || (ref.dep = createDep()), { // 跟踪依赖
target: ref, // 目标引用
type: TrackOpTypes.GET, // 操作类型为 GET
key: 'value' // 键为 'value'
})
} else {
trackEffects(ref.dep || (ref.dep = createDep())) // 生产模式下直接跟踪依赖
}
}
}
// 触发引用值的依赖
export function triggerRefValue(ref: RefBase<any>, newVal?: any) {
ref = toRaw(ref) // 获取原始引用
if (ref.dep) { // 如果有依赖集合
if (__DEV__) { // 开发模式下
triggerEffects(ref.dep, { // 触发依赖
target: ref, // 目标引用
type: TriggerOpTypes.SET, // 操作类型为 SET
key: 'value', // 键为 'value'
newValue: newVal // 新值
})
} else {
triggerEffects(ref.dep) // 生产模式下直接触发依赖
}
}
}
// 判断一个值是否是 Ref 类型
export function isRef<T>(r: Ref<T> | unknown): r is Ref<T>
export function isRef(r: any): r is Ref {
return !!(r && r.__v_isRef === true) // 检查是否有 __v_isRef 标志
}
// 创建一个 Ref 对象
export function ref<T extends object>(
value: T
): [T] extends [Ref] ? T : Ref<UnwrapRef<T>>
export function ref<T>(value: T): Ref<UnwrapRef<T>>
export function ref<T = any>(): Ref<T | undefined>
export function ref(value?: unknown) {
return createRef(value, false) // 调用 createRef 函数创建 Ref 对象
}
// 声明一个唯一的符号,用于标记浅引用
declare const ShallowRefMarker: unique symbol
// 定义 ShallowRef 类型,表示一个浅响应式引用
export type ShallowRef<T = any> = Ref<T> & { [ShallowRefMarker]?: true }
// 创建一个浅响应式引用
export function shallowRef<T extends object>(
value: T
): T extends Ref ? T : ShallowRef<T>
export function shallowRef<T>(value: T): ShallowRef<T>
export function shallowRef<T = any>(): ShallowRef<T | undefined>
export function shallowRef(value?: unknown) {
return createRef(value, true) // 调用 createRef 函数创建浅响应式引用
}
// 创建一个 Ref 对象的实现
function createRef(rawValue: unknown, shallow: boolean) {
if (isRef(rawValue)) { // 如果已经是 Ref 类型,直接返回
return rawValue
}
return new RefImpl(rawValue, shallow) // 创建一个新的 RefImpl 对象
}
// RefImpl 类的实现
class RefImpl<T> {
private _value: T // 响应式值
private _rawValue: T // 原始值
public dep?: Dep = undefined // 依赖集合
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) {
newVal = this.__v_isShallow ? newVal : toRaw(newVal) // 获取原始值
if (hasChanged(newVal, this._rawValue)) { // 如果值发生变化
this._rawValue = newVal // 更新原始值
this._value = this.__v_isShallow ? newVal : toReactive(newVal) // 更新响应式值
triggerRefValue(this, newVal) // 触发依赖
}
}
}
// 触发 Ref 的依赖
export function triggerRef(ref: Ref) {
triggerRefValue(ref, __DEV__ ? ref.value : void 0) // 调用 triggerRefValue 触发依赖
}
// 解包 Ref 的值
export function unref<T>(ref: T | Ref<T>): T {
return isRef(ref) ? (ref.value as any) : ref // 如果是 Ref 类型,返回其值,否则直接返回
}
// 定义浅解包处理器
const shallowUnwrapHandlers: ProxyHandler<any> = {
get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)), // 获取值时解包 Ref
set: (target, key, value, receiver) => {
const oldValue = target[key]
if (isRef(oldValue) && !isRef(value)) { // 如果旧值是 Ref,新值不是
oldValue.value = value // 更新 Ref 的值
return true
} else {
return Reflect.set(target, key, value, receiver) // 否则直接设置值
}
}
}
// 创建一个代理,用于解包对象中的 Ref
export function proxyRefs<T extends object>(
objectWithRefs: T
): ShallowUnwrapRef<T> {
return isReactive(objectWithRefs) // 如果对象已经是响应式的,直接返回
? objectWithRefs
: new Proxy(objectWithRefs, shallowUnwrapHandlers) // 否则创建代理
}
// 定义自定义 Ref 工厂函数的类型
export type CustomRefFactory<T> = (
track: () => void,
trigger: () => void
) => {
get: () => T
set: (value: T) => void
}
// 自定义 Ref 的实现
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 // 标记为 Ref 类型
constructor(factory: CustomRefFactory<T>) {
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) // 调用设置值的函数
}
}
// 创建一个自定义 Ref
export function customRef<T>(factory: CustomRefFactory<T>): Ref<T> {
return new CustomRefImpl(factory) as any // 创建 CustomRefImpl 实例
}
最主要函数:createRef
// 创建一个 Ref 对象的实现
function createRef(rawValue: unknown, shallow: boolean) {
if (isRef(rawValue)) { // 如果已经是 Ref 类型,直接返回
return rawValue
}
return new RefImpl(rawValue, shallow) // 创建一个新的 RefImpl 对象
}
// RefImpl 类的实现
class RefImpl<T> {
private _value: T // 响应式值
private _rawValue: T // 原始值
public dep?: Dep = undefined // 依赖集合
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) {
newVal = this.__v_isShallow ? newVal : toRaw(newVal) // 获取原始值
if (hasChanged(newVal, this._rawValue)) { // 如果值发生变化
this._rawValue = newVal // 更新原始值
this._value = this.__v_isShallow ? newVal : toReactive(newVal) // 更新响应式值
triggerRefValue(this, newVal) // 触发依赖
}
}
}
为什么通过构造函数来实现ref顶层响应式?
简单性和易用性:
ref
提供了一种简单的方式来创建响应式数据。通过直接使用value
属性,开发者可以轻松地访问和修改数据,而不需要额外的语法或复杂的结构。性能优化:
ref
的实现通常是针对特定的框架(如Vue.js)进行了优化,以确保在数据变化时能够高效地更新视图。使用Proxy
虽然可以实现响应式,但可能会引入额外的开销,尤其是在处理大量数据或复杂对象时。明确的语义:
ref
的设计使得数据的响应式行为非常明确。开发者知道ref
对象的value
属性是响应式的,而其他属性则不是。这种明确性有助于减少误解和错误。