unref用于统一处理ref和普通值:若为ref则返回.value,否则直接返回原值;常用于组合式函数中屏蔽参数类型差异,不触发依赖收集,且仅解一层。

在 Vue 3 的响应式系统中,unref 是一个非常实用的工具函数,它的核心作用就是**统一处理 ref 和普通值的取值逻辑**:如果是 ref,就返回其 .value;否则直接返回原值。这在编写可同时接收 ref 或普通值的组合式函数(composables)或工具方法时特别关键。
unref 的基本行为
unref 的逻辑非常简洁:
- 若传入的是 ref(即具有
.value属性的对象),则返回target.value - 若传入的是普通值(string / number / boolean / null / undefined / plain object 等),则原样返回
- 它不会对非 ref 对象做任何转换或包装,也不会报错
示例:
import { ref, unref } from 'vue'
const count = ref(10)
const name = 'Alice'
console.log(unref(count)) // 10
console.log(unref(name)) // 'Alice'
console.log(unref(42)) // 42
console.log(unref(null)) // null
在组合式函数中统一参数处理
当你写一个希望“既支持传 ref 也支持传原始值”的函数时,unref 能帮你屏蔽调用方的类型差异。
- 避免在函数内部反复写
typeof xxx === 'object' && 'value' in xxx ? xxx.value : xxx - 让函数签名更简洁、语义更清晰(比如接受
count: MaybeRef<number></number>) - 配合 TypeScript 使用时,
MaybeRef<t></t>类型本身就是基于unref语义定义的
例如一个防抖计算函数:
import { ref, unref, computed } from 'vue'
function useDebouncedValue(source, delay = 300) {
const raw = unref(source) // ✅ 统一取值
return computed(() => {
// 这里 raw 就是确定的普通值,无需再判断是否为 ref
return raw // 或做其他逻辑处理
})
}
// 调用方式都一样
const countRef = ref(5)
const countPlain = 5
useDebouncedValue(countRef) // ✅
useDebouncedValue(countPlain) // ✅
与 toValue 的区别(Vue 3.4+ 新增)
Vue 3.4 引入了 toValue,它和 unref 行为一致,但语义更明确:
-
unref主要用于“解包”,常见于内部逻辑或泛型推导 -
toValue更强调“获取最终值”,推荐在对外 API 或显式需要“求值”意图的场景使用 - 二者目前完全等价,
toValue(x) === unref(x)
例如:
import { toValue } from 'vue'
function formatValue(input) {
const value = toValue(input) // ? 语义更直白:我要这个值
return String(value).toUpperCase()
}
注意事项与常见误区
-
unref只解一层:对ref(ref(42))返回的是内层 ref,不是 42(如需深度解包,需自行递归或用shallowRef配合逻辑) - 不触发响应式依赖收集:它只是取值,不会让当前副作用(如
computed)自动追踪该 ref 的变化 - 不要在模板中直接用
unref(x)—— 模板里 ref 会自动解包,写{{ count }}就行,不用{{ unref(count) }} - 与
isRef搭配使用更安全:当需要分支逻辑(比如只对 ref 做某些操作)时,先用isRef判断再决定是否unref










