ref是vue 3自定义hook中管理原子化响应式状态的核心工具,适用于数字、布尔等简单值,需通过.value读写,不可解构破坏响应性。

在 Vue 3 自定义 Hook 中,ref 是管理单一响应式状态的核心工具。它不依赖组件实例,天然适合抽离到函数中封装逻辑,且能被 Composition API 的其他能力(如 watch、computed)直接消费。
ref 在自定义 Hook 中的典型用法
绝大多数基础状态类 Hook(如 useCounter、useMousePosition)都以 ref 创建初始值,并通过 .value 修改。关键在于:ref 返回的是一个响应式“引用对象”,不是原始值本身。
- 声明时用
const count = ref(0),不是let count = 0 - 读取时用
count.value,不能直接写count - 返回给组件时直接返回
count(整个 ref 对象),组件模板中可直接用{{ count }}—— Vue 会自动解包
什么时候该用 ref 而不是 reactive
ref 更适合管理简单、原子化的状态,比如数字、布尔、字符串、单个对象引用;而 reactive 更适合结构较深、属性较多的对象。
分析 Vue 3 Composition API 使用情况——审计响应式模式、可组合函数设计、ref 与 reactive 的选择、计算属性、watcher 使用及组件……
- ✅ 推荐用 ref:计数器数值、加载开关
loading、错误信息error、输入框绑定值searchText - ⚠️ 少用 reactive:除非你明确需要响应式地监听整个对象的多个字段变化(比如表单数据对象),否则用多个 ref 更清晰、更易调试
- ? 混合使用也常见:例如用 ref 存接口返回的数组
list = ref([]),同时用 reactive 管理分页参数params = reactive({ page: 1, size: 10 })
ref 和副作用配合的关键细节
在 Hook 内部调用 onMounted、watch、onUnmounted 等生命周期或响应式 API 时,ref 是安全的载体,但要注意异步回调中的 this 与作用域问题。
- watch 可直接监听 ref:
watch(count, (newVal) => {...}) - 异步请求后赋值必须用
.value:data.value = await api.get() - 组件卸载前取消副作用(如定时器、事件监听)可避免内存泄漏,ref 本身不负责清理,需手动处理
避免常见误用
ref 不是万能的,几个高频坑点要留意:
- ❌ 不要把 ref 当作普通变量解构:
const { value } = ref(0)会丢失响应性 —— 必须保持 ref 对象完整传递 - ❌ 不要在 ref 中存大型嵌套对象并期望深层响应 —— 此时应改用 reactive 或对子属性单独用 ref
- ✅ 正确解构方式(如果必须):
const countRef = ref(0); const { value: count } = countRef;,但仅限读取,赋值仍需countRef.value = ...
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









