Vue 3 中的响应式系统:ref 与 reactive 的对比与应用

server/2025/3/13 5:54:32/

Vue 3 的响应式系统是其核心特性之一,它允许开发者以声明式的方式构建用户界面。Vue 3 引入了两种主要的响应式 API:refreactive。本文将详细介绍这两种 API 的用法、区别以及在修改对象属性和修改整个对象时的不同表现,并提供完整的代码示例。

1. ref 和 reactive 的定义

1.1 ref

ref 用于定义基本类型数据和对象类型数据。使用 ref 创建的变量必须通过 .value 属性访问和修改其值。

javascript">import { ref } from 'vue';const count = ref(0); // 基本类型数据
const user = ref({ name: 'Alice', age: 20 }); // 对象类型数据console.log(count.value); // 0
console.log(user.value.name); // Alice

1.2 reactive

reactive 用于定义对象类型数据。它返回一个响应式对象,可以直接访问和修改其属性,而不需要通过 .value

javascript">import { reactive } from 'vue';const user = reactive({ name: 'Alice', age: 20 });console.log(user.name); // Alice

2. ref 和 reactive 的区别

2.1 创建变量的方式

  • ref 创建的变量必须使用 .value 访问。
  • reactive 创建的对象可以直接访问其属性。

2.2 重新分配对象

  • reactive 重新分配一个新对象会失去响应式(可以使用 Object.assign 去整体替换)。
  • ref 可以通过 .value 重新分配整个对象,且保持响应式。

3. 使用原则

3.1 基本类型数据

若需要一个基本类型的响应式数据,必须使用 ref

javascript">const count = ref(0);

3.2 对象类型数据

  • 若需要一个响应式对象,层级不深,refreactive 都可以。
  • 若需要一个响应式对象,且层级较深,推荐使用 reactive
javascript">const user = reactive({name: 'Alice',age: 20,address: {city: 'New York',zip: '10001'}
});

4. 修改对象属性和修改整个对象的区别

4.1 修改对象属性

当使用 reactive 创建响应式对象时,直接修改其属性会触发视图更新。

javascript">import { reactive } from 'vue';const student = reactive({name: 'Alice',age: 20
});student.name = 'Bob'; // 触发视图更新
student.age = 21;    // 触发视图更新

4.2 修改整个对象

当使用 reactive 创建响应式对象时,重新分配一个新对象会失去响应式,需要使用 Object.assign 去整体替换。

javascript">import { reactive } from 'vue';const student = reactive({name: 'Alice',age: 20
});// 错误的做法,会失去响应式
student = { name: 'Bob', age: 21 };// 正确的做法
Object.assign(student, { name: 'Bob', age: 21 }); // 触发视图更新

4.3 使用 ref 修改对象和属性

当使用 ref 创建响应式对象时,需要通过 .value 访问和修改其属性。

javascript">import { ref } from 'vue';const studentRef = ref({name: 'Alice',age: 20
});// 修改属性
studentRef.value.name = 'Bob'; // 触发视图更新
studentRef.value.age = 21;    // 触发视图更新// 修改整个对象
studentRef.value = { name: 'Charlie', age: 22 }; // 触发视图更新

5. 完整代码示例

以下是一个简单的 Vue 3 应用示例,展示了如何使用 refreactive 创建响应式数据,并演示了修改对象属性和修改整个对象的区别。

<template><div><p>Student (ref): {{ studentRef.value.name }}, {{ studentRef.value.age }}</p><button @click="updateStudentRef">Update Student (ref)</button><p>Student (reactive): {{ studentReactive.name }}, {{ studentReactive.age }}</p><button @click="updateStudentReactive">Update Student (reactive)</button></div>
</template><script>javascript">
import { ref, reactive } from 'vue';export default {setup() {// 使用 ref 创建响应式数据const studentRef = ref({name: 'Alice',age: 20});const updateStudentRef = () => {studentRef.value.name = 'Bob';studentRef.value.age = 21;};// 使用 reactive 创建响应式数据const studentReactive = reactive({name: 'Alice',age: 20});const updateStudentReactive = () => {studentReactive.name = 'Bob';studentReactive.age = 21;};return {studentRef,updateStudentRef,studentReactive,updateStudentReactive};}
};
</script>

6. 总结

Vue 3 的 refreactive 提供了灵活的响应式数据管理方式。ref 适合基本类型数据和需要显式访问 .value 的场景,而 reactive 适合对象类型数据,特别是层级较深的对象。理解它们的区别和使用场景,可以帮助开发者更有效地构建响应式应用。

通过本文的介绍和示例代码,希望你能更好地理解 Vue 3 中的响应式系统,并在实际项目中灵活运用 refreactive

文章来源:https://blog.csdn.net/qq_29752857/article/details/145364325
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ppmy.cn/server/164532.html

相关文章

mysql重学(一)mysql语句执行流程

思考 一条查询语句如何执行&#xff1f;mysql语句中若列不存在&#xff0c;则在哪个阶段报错一条更新语句如何执行&#xff1f;redolog和binlog的区别&#xff1f;为什么要引入WAL什么是Changbuf&#xff1f;如何工作写缓冲一定好吗&#xff1f;什么情况会引发刷脏页删除语句会…

【Linux指令/信号总结】粘滞位 重定向 系统调用 信号产生 信号处理

文章目录 1.>2. cat3.系统命令bash和shell和kernel权限只被认证一次粘滞位引入前提知识场景解释为什么普通用户&#xff08;无w权限&#xff09;可以删除文件&#xff1f;为什么普通用户通过sudo设置文件权限为000后仍能删除文件&#xff1f; 结论 粘滞位是干什么的&#xf…

穷举vs暴搜vs深搜vs回溯vs剪枝系列一>解数独

题目&#xff1a; 解析&#xff1a; 部分决策树&#xff1a; 代码设计&剪枝&回溯&#xff1a; 代码&#xff1a; class Solution {private boolean[][] row, col;private boolean[][][] gird; public void solveSudoku(char[][] board) {//下标->数字&#xff…

http 请求类型及其使用场景

HTTP 请求方法在设计 API 时至关重要&#xff0c;它们提供了标准化的方式来描述对资源的不同操作。根据不同的业务需求&#xff0c;使用合适的 HTTP 方法来完成不同的操作有助于提高 API 的可读性和一致性。 各请求方法的区别 GET 是用来获取数据&#xff0c;常用于查询操作&…

使用Pygame制作“青蛙过河”游戏

本篇博客将演示如何使用 Python Pygame 从零开始编写一款 Frogger 风格的小游戏。Frogger 是一款早期街机经典&#xff0c;玩家需要帮助青蛙穿越车水马龙的马路到达对岸。本示例提供了一个精简原型&#xff0c;包含角色移动、汽车生成与移动、碰撞检测、胜利条件等关键点。希望…

什么情况下,C#需要手动进行资源分配和释放?什么又是非托管资源?

扩展&#xff1a;如何使用C#的using语句释放资源&#xff1f;什么是IDisposable接口&#xff1f;与垃圾回收有什么关系&#xff1f;-CSDN博客 托管资源的回收有GC自动触发&#xff0c;而非托管资源需要手动释放。 在 C# 中&#xff0c;非托管资源是指那些不由 CLR&#xff08;…

关于bash内建echo输出多行文本

echo命令 使用下述命令可以判断当前使用的echo命令是内建命令还是外部命令 type echo有下述输出&#xff0c;说明是内建命令 bash的内建命令输出多行文本时会拆分多次写入 如果希望不拆分多次写入&#xff0c;可以借用tee工具 tee工具可以将命令的输出同时发送到终端和文件…

第四章-SUSE- Rancher-容器高可用与容灾测试-RKE2(容灾测试)

系列文章目录 第一章-SUSE- Rancher-容器高可用与容灾测试-RKE2-外置Mysql&#xff08;主备集群搭建&#xff09;-CSDN博客 第二章-SUSE- Rancher-容器高可用与容灾测试-RKE2-集群搭建&#xff08;外置Mysql&#xff09; 第三章-SUSE- Rancher-容器高可用与容灾测试-Rancher-…