vue3 ref实现
Vue3 中 ref 的实现原理
Vue3 的 ref 函数用于创建一个响应式引用对象,适用于基本类型或复杂类型的响应式处理。以下是其核心实现逻辑和使用方法。
ref 的基本用法
通过 ref 创建的响应式对象会返回一个带有 value 属性的对象,访问或修改数据需要通过 .value 操作。
import { ref } from 'vue';
const count = ref(0); // 创建响应式引用
console.log(count.value); // 读取值
count.value = 1; // 修改值
ref 的实现原理
Vue3 的 ref 本质上是对 reactive 的封装,将传入的值包装为一个带有 value 属性的对象,再通过 reactive 实现响应式。
-
包装对象
ref将原始值或对象转换为{ value: ... }的形式,确保统一通过.value访问。 -
响应式处理
内部调用reactive对包装后的对象进行响应式代理,依赖收集和触发更新通过reactive系统完成。
简化版实现逻辑:
function ref(value) {
return reactive({ value });
}
ref 与 reactive 的区别
-
适用类型
ref适用于基本类型(如number、string)和对象,而reactive仅适用于对象。 -
访问方式
ref需要通过.value访问,reactive直接访问属性。
-
自动解包
在模板中使用时,ref会自动解包(无需.value),但在 JavaScript 中仍需显式使用。
源码中的优化
实际 Vue3 源码中,ref 并非直接调用 reactive,而是通过 RefImpl 类实现,包含额外的性能优化和类型标记:
class RefImpl {
constructor(value) {
this._value = value;
this.dep = new Set(); // 依赖收集
}
get value() {
trackRef(this); // 依赖追踪
return this._value;
}
set value(newVal) {
this._value = newVal;
triggerRef(this); // 触发更新
}
}
使用场景建议
- 基本类型:优先使用
ref,因为reactive无法直接代理基本类型。 - 模板引用:通过
ref获取 DOM 元素。 - 逻辑复用:在组合式函数中返回
ref便于外部解构使用。
// 获取 DOM 元素
const inputRef = ref(null);
onMounted(() => {
inputRef.value.focus();
});
类型标注(TypeScript)
通过泛型指定 ref 的类型:
const count = ref<number>(0); // 明确类型为 number


