以观书法
108.85M · 2026-02-05
在 Vue 3 中,响应式系统经历了重构,ref 和 reactive 成为了响应式编程的两大核心 API。它们看似相似,却承担了不同的角色。理解它们的实现机制,能够帮助我们更好地掌握 Vue 3 的响应式原理,也能在开发中写出更高效、更优雅的代码。
其次,这个问题也算是面试中老生常谈的问题,千篇一律的八股文让你的回答没有亮点,本文从源码角度分析 reactive 和 ref 的区别, 让你在面试中轻松拿捏面试官
reactive 主要用于将对象变成响应式代理,适合复杂的对象和集合类型。
就是
ref 用于包装任意类型的值,包括基本类型,实现响应式引用。
不知道怎么进行源码阅读的同学,可以看博主之前的文章,已经做了详细介绍,在此就不赘述了~
首先你好这个人那边去。那个你说的这个你们都登记了。嗯但是觉得设置初始的响应式变量
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue Effect Test</title>
<!-- 引入你本地 clone 的 vue.global.js -->
<script src="../../../../vue/dist/vue.global.js"></script>
</head>
<body>
<div id="text"></div>
<button id="btn">count++</button>
<script>
const { reactive, ref, effect } = Vue;
// 创建响应式数据
const state = reactive({
count1: 1,
});
const count2 = ref(1);
// 绑定 effect:依赖收集 + 自动更新
effect(() => {
document.getElementById('text').innerText =
`当前 count 值:${state.count1}, ${count2.value}`;
});
document.getElementById('btn').onclick = () => {
state.count1++;
count2.value++;
};
</script>
</body>
</html>
从下图可以看到createReactiveObject最后返回的是一个 proxy 对象
当我们访问count1属性时,本质是执行reactive模块下的baseHandler.ts中BaseReactiveHandle类中的get方法,可以看到track方法是对对象的属性进行依赖收集的
ref声明的响应式变量是通过createRef创建的,
createRef返回的是RefImpl实例
当我们通过.value访问ref数据时,触发get操作,可以看到track操作是对value做的响应式(这是和reactive的本质区别),最后get返回value值
重点关注RefImpl中constructor的toReactive方法,toReactive 会判断 value 是对象就调用 reactive(value),不是对象就原样返回
| 方面 | reactive | ref |
|---|---|---|
| 支持类型 | 只能代理对象 | 支持基础类型和对象 |
| 实现机制 | Proxy 深度代理 | getter/setter 包裹 .value |
| 响应式深度 | 访问时懒代理嵌套对象 | 对象 .value 内部递归 reactive |
| 依赖收集 | Proxy get | .value getter |
| 触发更新 | Proxy set | .value setter |
| 使用场景 | 状态对象及复杂数据 | 基础类型值或包裹对象 |
ref是对value做的响应式,所以watch时候,不到对象属性的改变,得配合deep使用
原创不易,如果对你有帮助,帮忙点攒、收藏、关注~