JS:两个函数:ref与unref

  1. ref
    1. 定义:
    2. 为什么需要 ref
  2. unref
    1. 定义:
    2. 为什么需要 unref?
    3. unref 返回值的类型
      1. 当传入普通值(非响应式)
      2. 当传入 Ref<T>
      3. 当传入 ComputedRef<T>
对比项 ref unref
目的 创建响应式引用 读取响应式引用的值
输入 任意值(如 5, "text" 任意值(可能是 ref/computed/普通值)
输出 Ref<T> 对象(带 .value T(原始值)
是否响应式 ✅ 是 ❌ 否(只是读取)
典型用途 在组件中声明响应式状态 在工具函数中安全处理不确定类型的参数

ref

定义:

ref 是一个函数,用于将一个普通值(primitive value)包装成一个响应式的“引用对象”(Reactive Reference)。

import { ref } from 'vue'

const count = ref(0)
// count 现在是一个对象:{ value: 0 }

console.log(count.value) // 0

count.value = 1 // 修改值
console.log(count.value) // 1

为什么需要 ref

ref 让原始值也能参与 Vue 的响应式系统。

  • Vue 的响应式系统基于 JavaScript Proxy,而 Proxy 只能代理对象
  • numberstringboolean 这些原始类型(primitive)无法被 Proxy 直接追踪
  • 所以 Vue 用 ref 把它们“装进一个对象里”({ value: ... }),从而实现响应式。

unref

定义:

unref 是一个工具函数,用于“安全地获取值”:如果参数是 refcomputed,返回它的 .value;否则直接返回原值。

import { ref, computed, unref } from 'vue'

const a = ref(10)
const b = computed(() => a.value * 2)
const c = "hello"

console.log(unref(a)) // 10 (等价于 a.value)
console.log(unref(b)) // 20 (等价于 b.value)
console.log(unref(c)) // "hello" (普通值直接返回)

为什么需要 unref

在编写通用函数或组合式函数(composables) 时,你可能不确定传入的参数是:

  • 一个普通值(如 "px"
  • 还是一个 ref(如 ref("px")
  • 或一个 computed(如 computed(() => "44px")

unref 让你不用关心类型,统一安全地取出值

// ❌ 危险:如果传入的是 ref,会出错
function setPadding(el, padding) {
  el.style.padding = padding + 'px' // 如果 padding 是 ref,变成 "[object Object]px"
}

// ✅ 安全:用 unref
function setPadding(el, padding) {
  el.style.padding = unref(padding) + 'px'
}

// 调用方式更灵活:
setPadding(el, 10)           // 普通数字
setPadding(el, ref(10))      // ref
setPadding(el, computed(() => 10)) // computed

unref 返回值的类型

unref(x) 的返回类型 = x 如果是普通值,则返回 x 的类型;如果 xRef<T>ComputedRef<T>,则返回 T

当传入普通值(非响应式)

返回类型 = 输入类型

const str = "hello"
const num = 42
const obj = { name: "Alice" }

// unref 直接返回原值,类型不变
const a = unref(str) // type: string
const b = unref(num) // type: number
const c = unref(obj) // type: { name: string }

当传入 Ref<T>

返回类型 = T(即 .value 的类型)

import { ref } from 'vue'

const count = ref(10)        // Ref<number>
const title = ref("Hello")   // Ref<string>
const user = ref({ id: 1 })  // Ref<{ id: number }>

const a = unref(count) // type: number
const b = unref(title) // type: string
const c = unref(user)  // type: { id: number }

当传入 ComputedRef<T>

import { computed } from 'vue'

const double = computed(() => 5 * 2) // ComputedRef<number>
const fullName = computed(() => "张三") // ComputedRef<string>

const a = unref(double)    // type: number
const b = unref(fullName)  // type: string

×

喜欢就点赞,疼爱就打赏