reactive 和 ref 的区别和联系

在 Vue3 的组合式 API (Composition API)中,ref 和 reactive 是用于创建响应式数据的两个核心函数。尽管二者都用于实现响应式数据,但在使用方式和适用场景上存在一些区别。

1. 基本概念

1.1 ref

用途:用于定义 基本类型 (如字符串、数字、布尔值)和 简单对象 的响应式数据。

返回值:一个包含 value 属性的 响应式对象

特点:

1、对于基本类型,ref 会将其包装在一个带有 .value 属性的对象中。

2、对于对象类型,ref 也会对其内部属性进行深度响应式转换。

1.2 reactive

用途:用于定义 复杂对象(如对象、数组)的响应式数据。

返回值:原始对象的 响应式代理 proxy

特点:

1、对传入的对象进行 深度响应式 转换,即对象内部所有嵌套的属性也都是响应式的。

2、返回的对象看起来与原始对象相同,不用通过 .value 访问属性。

2. 具体描述

2.1 深度响应性

1、ref

1)对于 基本类型,ref 只包装值本身。

2)对于 对象类型 ,ref 会对对象内部进行 深度响应式 处理,与 reactive 类似。

示例

javascript 复制代码
const obj = ref({
  a: 1,
  b: {
    c: 2
  }
});

obj.value.b.c = 3; // 响应式更新

2、reactive

1)总是对传入的对象进行 深度响应式 处理。

示例

javascript 复制代码
const obj = reactive({
  a: 1,
  b: {
    c: 2
  }
});

obj.b.c = 3; // 响应式更新

注意 :在 Vue 3 中,reactive 和 ref 对对象类型的数据都会进行深度响应式处理。

2.2 解构问题

解构赋值时的响应性丢失

1、reactive 对象在解构时会丢失响应性。

javascript 复制代码
<template>
  <div>state.count:{{ state.count }}</div>
</template>

<script setup>
import { reactive } from 'vue';
const state = reactive({
  count: 0
});
let { count } = state;
console.log('count:', count);
count++; // 不是响应式的,界面不会更新
console.log('count:', count);
</script>

解决方案 :使用 toRefs reactive对象转换为响应式引用

javascript 复制代码
import { reactive, toRefs } from 'vue';
const state = reactive({
  count: 0
});
const { count } = toRefs(state);
console.log('count:', count);
count.value++; // 响应式更新,界面会更新
console.log('count:', count);

2、ref 在解构时同样也会丢失响应性,因为解构操作提取的是当前值,而不是保持对 ref 对象的响应式引用。

javascript 复制代码
import { ref } from 'vue';
const countRef = ref(0);
// 解构 ref
const { value: countValue } = countRef;
// 修改 ref 的值
countRef.value++;
console.log('countValue:', countValue); // 输出 0,因为 countValue 已经解构出来,并且不再响应

// 直接使用 ref 的 .value 属性
console.log('countRef.value:', countRef.value); // 输出 1,因为 countRef 仍然是响应式的

2.3 响应式转换的辨识

1、ref 创建的响应式对象有一个 Ref 标记,可以通过 isRef 进行判断。

javascript 复制代码
import { ref, isRef } from 'vue';
const count = ref(0);
console.log(isRef(count)); // true

2、reactive 创建的响应式对象可以通过 isReactive 进行判断。

javascript 复制代码
import { reactive, isReactive } from 'vue';
const state = reactive({ count: 0 });
console.log(isReactive(state)); // true

3. 何时使用

1、ref

当需要创建一个简单的、可响应的基本类型数据(如字符串、数字、布尔值)时。

当需要从 reactive 对象中解构某个属性,并保持响应性时,可以使用 toRef 或 toRefs。

2、reactive

当需要创建包含多个属性的对象或数组,并希望所有嵌套属性都具有响应性时。

当需要在模板中频繁访问对象的多个属性时,reactive 会比多个 ref 更简洁。

相关推荐
前端小巷子3 分钟前
跨域问题解决方案:开发代理
前端·javascript·面试
前端_逍遥生3 分钟前
Chrome 插件开发到发布完整指南:从零开始打造 TTS 朗读助手
前端·chrome
JohnYan3 分钟前
Bun技术评估 - 07 S3
javascript·后端·bun
Mintopia3 分钟前
Three.js 材质与灯光:一场像素级的光影华尔兹
前端·javascript·three.js
天涯学馆5 分钟前
JavaScript 跨域、事件循环、性能优化面试题解析教程
前端·javascript·面试
掘金一周13 分钟前
别再用 100vh 了!移动端视口高度的终极解决方案| 掘金一周7.3
前端·后端
晴殇i15 分钟前
CSS 迎来重大升级:Chrome 137 支持 if () 条件函数,样式逻辑从此更灵活
前端·css·面试
源码站~17 分钟前
基于Flask+Vue的豆瓣音乐分析与推荐系统
vue.js·python·flask·毕业设计·毕设·校园·豆瓣音乐
咚咚咚ddd17 分钟前
cursor mcp实践:网站落地页性能检测报告(browser-tools)
前端
MiyueFE18 分钟前
让我害怕的 TypeScript 类型 — — 直到我学会了这 3 条规则
前端·typescript