Vue3 中 ref 和 reactive 的区别

核心区别

特性 ref reactive
适用数据类型 基本类型和对象 仅对象
访问方式 需要通过 .value 访问 直接访问
模板中使用 自动解包(无需.value) 直接使用
重新赋值 可以重新赋值整个对象 不能替换整个响应式对象
TypeScript支持 更好的类型推断 嵌套属性类型推断可能复杂

详细解析

1. 基本用法

ref:

javascript

import { ref } from 'vue'

const count = ref(0) // 创建响应式基本值
const user = ref({ name: 'John' }) // 也可以用于对象

// 访问/修改需要.value
console.log(count.value) // 0
count.value++

reactive:

javascript

import { reactive } from 'vue'

const state = reactive({
  count: 0,
  user: { name: 'John' }
})

// 直接访问
console.log(state.count) // 0
state.count++

2. 模板中使用区别

ref (自动解包):

html

<template>
  <div>{{ count }}</div> <!-- 不需要.value -->
</template>

reactive:

html

<template>
  <div>{{ state.count }}</div>
</template>

3. 重新赋值能力

ref 允许替换整个值:

javascript

const user = ref({ name: 'Alice' })
user.value = { name: 'Bob' } // 完全替换 - 可行

reactive 不能替换整个对象:

javascript

const state = reactive({ count: 0 })
state = { count: 1 } // 错误!会失去响应性

4. 解构行为

ref 解构后仍保持响应性:

javascript

const count = ref(0)
const { value } = count // 仍然响应式

reactive 解构会失去响应性:

javascript

const state = reactive({ count: 0 })
const { count } = state // 失去响应性!

使用场景建议

使用 ref 当:

  • 需要响应式基本类型(数字、字符串等)

  • 需要重新分配整个对象引用

  • 需要简单的值传递

使用 reactive 当:

  • 处理一组逻辑相关的状态

  • 不需要重新分配整个对象

  • 想要更简洁的对象访问语法

性能考虑

两者在性能上没有显著差异,选择应基于代码组织需求而非性能。

最佳实践

  1. 在组合式函数中返回多个值时,通常使用 ref 以便解构后仍保持响应性

  2. 对于复杂的状态对象,使用 reactive 可以获得更干净的访问语法

  3. 可以混合使用 - 在 reactive 对象中包含 ref 会自动解包

javascript

const count = ref(0)
const state = reactive({
  count, // 自动解包 - 模板中可以直接state.count
  message: 'Hello'
})
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐