Vue3系列 - 模板引用(Refs)的实现
Vue3中的模板引用(Refs)允许我们直接访问DOM元素或子组件实例,其实现主要在src/v3/reactivity/ref.ts中。
模板引用的核心实现:
- Ref接口:定义了具有响应式
value属性的对象。
export interface Ref<T = any> {
value: T
[RefSymbol]: true
dep?: Dep
[RefFlag]: true
}- ref函数:创建一个包装对象,使原始值变成响应式。
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实现:内部使用
defineReactive来实现响应式。
function createRef(rawValue: unknown, shallow: boolean) {
if (isRef(rawValue)) {
return rawValue
}
const ref: any = {}
def(ref, RefFlag, true)
def(ref, ReactiveFlags.IS_SHALLOW, shallow)
def(
ref,
'dep',
defineReactive(ref, 'value', rawValue, null, shallow, isServerRendering())
)
return ref
}- isRef函数:检查一个值是否为ref对象。
export function isRef(r: any): r is Ref {
return !!(r && (r as Ref).__v_isRef === true)
}- unref函数:如果参数是ref则返回其
.value,否则返回参数本身。
export function unref<T>(ref: T | Ref<T>): T {
return isRef(ref) ? (ref.value as any) : ref
}模板引用为访问底层DOM和组件实例提供了便捷的方式,同时保持了Vue响应式系统的一致性。