Vue 3 中 ref 和 reactive 的区别与使用场景

refreactive 是 Vue 3 组合式 API 中两个核心的响应式函数,它们有不同的使用场景。

核心区别

特性 ref reactive
数据类型 任何类型(基本类型、对象、数组) 仅对象类型(Object、Array、Map、Set)
访问方式 需要 .value 直接访问属性
重新赋值 支持(保持响应式) 不支持(会失去响应式)
模板使用 自动解包(不需要 .value 直接使用
解构 需要 toRefs 保持响应式 需要 toRefs 保持响应式

详细解释

1. ref - 引用响应式变量

const articles = ref([])

为什么在这里使用 ref?

// 这些操作都需要重新赋值,ref 能保持响应式
articles.value = []                    // 清空数组
articles.value = newArticles           // 替换整个数组
articles.value = [...articles.value, newArticle] // 创建新数组

// 在模板中自动解包,不需要 .value
// <div v-for="article in articles">

ref 的典型使用场景:

  • 需要重新赋值的数组
  • 基本类型数据(string、number、boolean)
  • 可能被完全替换的对象
  • 需要响应式包装的任何值

2. reactive - 响应式对象

const newArticle = reactive({
  title: '',
  excerpt: '',
  content: ''
})

为什么在这里使用 reactive?

// 直接修改属性,不需要 .value
newArticle.title = '新标题'
newArticle.excerpt = '新摘要'
newArticle.content = '新内容'

// 整个表单对象作为一个整体,属性之间有关联
// 不需要重新赋值整个对象

reactive 的典型使用场景:

  • 表单对象
  • 配置对象
  • 相关联的一组数据
  • 不需要重新赋值的复杂对象

实际代码对比

ref 示例

// 基本类型
const count = ref(0)
count.value++  // 需要 .value

// 数组
const list = ref([])
list.value.push('item')  // 需要 .value
list.value = []          // 可以重新赋值

// 在模板中:自动解包
// <div>{{ count }}</div>
// <div v-for="item in list">

reactive 示例

// 对象
const user = reactive({
  name: 'John',
  age: 25
})
user.name = 'Jane'  // 直接访问,不需要 .value

// 不能重新赋值
// user = { name: 'Bob' }  // 这会失去响应式(错误)

// 在模板中:直接使用属性
// <div>{{ user.name }}</div>

什么时候该用哪个?

使用 ref 的情况:

// 1. 基本类型
const isLoading = ref(false)
const page = ref(1)
const searchQuery = ref('')

// 2. 需要重新赋值的数组
const items = ref([])
const selectedItems = ref([])

// 3. 可能被替换的对象
const config = ref({ theme: 'light' })
config.value = { theme: 'dark' }  // 可以替换

使用 reactive 的情况:

// 1. 表单对象
const form = reactive({
  username: '',
  password: '',
  remember: false
})

// 2. 相关联的配置
const settings = reactive({
  theme: 'dark',
  language: 'zh-CN',
  notifications: true
})

// 3. 复杂的状态对象
const state = reactive({
  user: null,
  permissions: [],
  preferences: {}
})

特殊情况处理

解构 reactive 对象

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

// 解构会失去响应式(错误)
const { count, name } = state

// 使用 toRefs 保持响应式(正确)
const { count, name } = toRefs(state)
count.value++  // 现在需要 .value

ref 解包

const objectRef = ref({ count: 0 })

// 在模板中自动解包
// <div>{{ objectRef.count }}</div>

// 在 JavaScript 中需要 .value
objectRef.value.count++

总结

  • 用 ref:基本类型、需要重新赋值的值
  • 用 reactive:不需要重新赋值的对象、表单数据

愿你我都能在各自的领域里不断成长,勇敢追求梦想,同时也保持对世界的好奇与善意!

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐