困惑我好久了这代码,我ts白痴,我不刻印脑子里我不叫小old弟:
function ref<T>(value: T): Ref<UnwrapRef<T>>
interface Ref<T>{
value: T
}
Vue3 Composition API中ref函数的类型定义。
用来创建一个响应式引用(Reactive Reference)。
ref<T>(value: T): Ref<UnwrapRef<T>>:
ref 函数的 类型签名。
<T>:泛型参数,表示传入的值的类型。value: T:ref接收一个任意类型的值value。Ref<UnwrapRef<T>>:返回一个Ref对象,其内部值value的类型是UnwrapRef<T>。
UnwrapRef<T>:递归解包嵌套的Ref类型:
-
如果
T本身是一个Ref,比如Ref<number>,那么UnwrapRef<T>会提取出number。 -
如果
T是一个对象,并且某些属性是Ref,它们会被解包成原始类型。
示例:
const numRef = ref(10); // Ref<number>
const objRef = ref({ count: 1 });; // Ref<{ count: number }>
interface Ref<T>
Ref是一个接口:
interface Ref<T> {
value: T
}
-
value是Ref的核心属性,访问或修改它时会触发Vue的响应式更新。 -
T是存储的值的类型。
import { ref } from 'vue';
// 创建一个 Ref<number>
const count = ref(0);
// 访问值
console.log(count.value); // 0
// 修改值 (会触发响应式更新)
count.value = 10;
UnwrapRef<T>嵌套
vue3 的 响应式系统会 自动解包嵌套的Ref,所以UnwrapRef确保类型正确匹配运行时行为。
const innerRef = ref(10);
const outerRef = ref(innerRef); // Ref<number>而不是Ref<Ref<number>>
- 运行时,
outerRef.value直接是number(不是Ref<number>) UnwrapRef确保类型系统知道这一点。
import { ref } from 'vue';
// 1. ref(10) -> Ref<number>
const count = ref(10);
// 2. ref({ count: ref(1) }) -> Ref<{ count: number }> (自动解包)
const obj = ref({
count: ref(1), // 嵌套 Ref 会被解包
});
console.log(obj.value.count); // 1 (不是 Ref,而是 number)
总结
-
ref(value)返回一个Ref对象,其.value属性是响应式的。 -
UnwrapRef<T>确保嵌套的Ref被正确解包,使类型系统匹配Vue的运行时行为。 -
Ref<T>是一个简单的接口,包含value: T,用于存储响应式值。
这在 Vue 3 的 Composition API 中非常重要,因为它允许我们创建基本类型(如 number、string)的响应式变量,而 reactive() 仅适用于对象。