Vue 中 ref 和 reactive 的区别与联系是什么?

探讨 Vue 3 的 Composition API 中 ref 和 reactive 的区别与应用场景,分析它们各自的优缺点。

Vue 中等 Composition API 响应式 Reactives

在 Vue 3 的 Composition API 中,refreactive 都是用于创建响应式数据的工具,但它们在使用方式、适用场景和内部机制上有所不同。以下是它们的区别和联系:

ref

ref 用于创建一个响应式引用,适用于基本类型(如字符串、数字)或对象。它返回一个带有 value 属性的对象,访问或修改值时必须使用 .value

import { ref } from 'vue';

const count = ref(0); // 创建 ref
console.log(count.value); // 0 (访问值)
count.value = 1; // 修改值

在模板中,ref 自动解包,无需 .value

<template>
  <div>{{ count }}</div> <!-- 直接显示值 -->
</template>

reactive

reactive 用于创建一个响应式对象,适用于对象或数组。它返回一个代理对象,可以直接访问和修改属性。

import { reactive } from 'vue';

const state = reactive({ count: 0 }); // 创建 reactive 对象
console.log(state.count); // 0 (直接访问属性)
state.count = 1; // 直接修改属性

区别

  1. 使用方式
    • ref 必须在 JavaScript 中使用 .value 访问值(模板中自动解包)。
    • reactive 可以直接访问属性(无需 .value)。
  2. 适用类型
    • ref 支持所有类型(基本类型、对象等)。
    • reactive 仅支持对象类型(对象、数组等),不适用于基本类型(如字符串、数字)。
  3. 响应性触发
    • ref 的响应性基于其 value 属性的变化。
    • reactive 的响应性基于对象属性的变化。
  4. 模板行为
    • ref 在模板中自动解包(显示值时省略 .value)。
    • reactive 对象的属性在模板中直接使用。
  5. 重新赋值
    • ref 允许直接重新赋值(如 count.value = newValue)。
    • reactive 对象不能整体替换(会丢失响应性),只能修改属性。

联系

  • 共同目标:两者都基于 Vue 的响应式系统(使用 Proxy),用于追踪数据变化并触发视图更新。
  • 内部机制:当 ref 接收一个对象时,内部会调用 reactive 来处理(如 ref({}) 等价于 reactive({}) 的封装)。
  • 组合使用:在 Composition API 中,可以结合使用(例如,用 ref 管理基本类型,用 reactive 管理复杂状态对象)。
  • 响应性原理:都依赖依赖收集和触发机制,确保数据变化时组件重新渲染。