vue的ref实现原理
Vue 的 ref 实现原理
Vue 的 ref 是一个用于响应式数据绑定的核心 API,其实现原理主要涉及以下几个关键点:
响应式数据的基础
Vue 3 使用 Proxy 对象实现响应式数据,而 ref 是对基本数据类型(如 number、string、boolean)的封装。由于 Proxy 无法直接代理基本类型,ref 通过将其包装为一个对象({ value: ... })来实现响应式。
ref 的核心实现
ref 的核心逻辑是将传入的值包装为一个带有 value 属性的对象,并通过 ReactiveEffect 和 track/trigger 机制实现依赖收集和触发更新。
function ref(value) {
return createRef(value, false);
}
function createRef(rawValue, shallow) {
if (isRef(rawValue)) {
return rawValue;
}
return new RefImpl(rawValue, shallow);
}
class RefImpl {
constructor(value, __v_isShallow) {
this.__v_isShallow = __v_isShallow;
this.dep = undefined;
this.__v_isRef = true;
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);
}
}
}
依赖收集与触发更新
trackRefValue:在读取ref.value时,会调用track函数收集当前活跃的副作用(如effect或computed)。triggerRefValue:在修改ref.value时,会调用trigger函数触发依赖该ref的副作用重新执行。
模板中的自动解包
在 Vue 模板中,ref 会被自动解包,无需通过 .value 访问:
<template>
<div>{{ count }}</div> <!-- 自动解包,无需写 count.value -->
</template>
<script setup>
const count = ref(0);
</script>
与 reactive 的区别
ref适用于基本类型和对象,访问需通过.value。reactive仅适用于对象,直接访问属性,无需.value。
ref 的实现体现了 Vue 响应式系统的核心思想,通过封装和依赖管理实现数据变化到视图更新的自动化。







