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 类似。

示例

const obj = ref({
  a: 1,
  b: {
    c: 2
  }
});

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

2、reactive 

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

示例

const obj = reactive({
  a: 1,
  b: {
    c: 2
  }
});

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

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

2.2 解构问题

解构赋值时的响应性丢失

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

<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 对象转换为响应式引用

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 对象的响应式引用。

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 进行判断。

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

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

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 更简洁。

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值