大宇宇宇
发布于 2025-09-03 / 17 阅读
1
0

ref和reactive的区别

Vue3 中,响应式系统是其核心特性之一。Vue 3 提供了两种主要的方式来创建响应式数据:ref 和 reactive。它们都属于 Composition API 的一部分,用于帮助开发者更灵活地管理组件的状态。

虽然两者都可以实现响应式,但在底层机制、使用方式和适用场景上存在显著差异。本文将详细介绍 ref 与 reactive 的区别,并通过代码示例说明它们各自的使用场景。

一、基本概念

1. ref

ref 用于创建一个响应式的引用类型(通常是基本类型如 number, string, boolean,也可以是对象)。

它返回一个带有 .value 属性的对象,访问或修改值时必须通过 .value。

在模板中使用时,无需加 .value,Vue 会自动解包。

2. reactive

reactive 用于创建一个深层响应式的对象(只能是对象,不能是基本类型)。

返回的是原始对象的代理(Proxy),对属性的访问和修改都是直接操作原对象的属性。

不需要使用 .value,但也不能重新赋值整个对象。

二、对比分析

特性

ref

reactive

数据类型支持

基本类型 + 对象

只支持对象

是否需要 .value

是否可重新赋值

是(整个 ref 可以被替换)

否(不能替换整个对象)

深层响应式

是(整个 ref 可以被替换)

否(不能替换整个对象)

解包能力(在模板中)

自动解包 —

三、使用场景

场景 1:处理基本类型的响应式数据

当你需要响应式地管理一个数字、字符串或者布尔值时,推荐使用 ref。

Vue
<template>
  <div>计数器:{{ count }}</div>
  <button @click="increment">+1</button>
</template>

<script setup>
import { ref } from 'vue'

const count = ref(0)
function increment() {
  count.value++
}
</script>

在这个例子中,count 是一个基本类型值,用 ref 包裹后即可实现响应式更新。

场景 2:处理复杂对象或嵌套结构

当你要管理一个对象或者包含多个字段的数据结构时,可以使用 reactive。

Vue
<template>
  <div>
    用户名:{{ user.name }}<br />
    年龄:{{ user.age }}
  </div>
  <button @click="increaseAge">年龄+1</button>
</template>

<script setup>
import { reactive } from 'vue'

const user = reactive({
  name: '张三',
  age: 25
})

function increaseAge() {
  user.age++
}
</script>

这里我们使用 reactive 来创建一个响应式对象,可以直接操作其属性而不需要 .value。

场景 3:在函数之间传递响应式引用

由于 ref 是一个对象,它可以在函数间安全地传递,并保持响应性。

Js
import { ref } from 'vue'

function useCounter() {
  const count = ref(0)
  function increment() {
    count.value++
  }
  return { count, increment }
}

export default {
  setup() {
    const { count, increment } = useCounter()
    return { count, increment }
  }
}

在这种情况下,ref 非常适合封装可复用的状态逻辑。

场景 4:避免响应式丢失

如果你把一个 reactive 对象的某个属性赋值给另一个变量,这个新变量将不再是响应式的。

Js
import { reactive } from 'vue'

const state = reactive({ count: 0 })
let num = state.count // ❌ num 不再是响应式的
num++
console.log(state.count) // 输出 0,不会触发更新
此时应使用 ref:

Js
import { ref } from 'vue'

const count = ref(0)
let num = count // ✅ num.value 是响应式的
num.value++
console.log(count.value) // 输出 1,正确响应

四、总结与建议

使用情况

推荐方式

基本类型值(number, string, boolean)

ref

复杂对象或状态集合

reactive

函数之间共享状态

ref

需要重新赋值整个变量

ref

希望模板中简洁写法

ref(自动解包)

五、结语

在 Vue 3 的开发中,理解 ref 和 reactive 的区别是非常重要的。合理选择合适的方式不仅可以提高代码的可读性和维护性,还能避免一些潜在的响应式陷阱。

Vue 3 的响应式系统基于 Proxy 和 Reflect 实现,性能优秀且功能强大。如果想进一步了解底层原理,可以查阅 Vue 3 响应式系统源码。


评论