当前位置: 首页 > news >正文

vue3<script setup>中使用reactive包裹的对象被重新赋值失去响应式原因和解决方式

在 Vue 3 的 <script setup> 语法中,如果使用 reactive 包裹的对象被重新赋值为一个新的对象,那么这个新对象将不再是响应式的。这是因为 reactive 函数只会在其被调用时使其参数对象成为响应式的,而后续对该变量的重新赋值(特别是赋值为一个新对象)并不会自动使新对象也变成响应式的。

原因

Vue 3 的响应式系统是基于 ES6 的 Proxy 实现的。当使用 reactive 包裹一个对象时,Vue 会创建一个该对象的 Proxy 实例,并返回这个 Proxy 实例。当修改这个 Proxy 实例的属性时,Vue 能够捕获这些修改并触发视图更新。但是,如果将 reactive 返回的 Proxy 实例重新赋值为一个全新的对象,那么这个新对象就没有被 Vue 的响应式系统处理过,因此它不会触发视图更新。

解决方式

  1. 避免重新赋值
    最直接的方式是避免对 reactive 返回的对象进行整体重新赋值。如果你需要更新对象的内容,应该直接修改对象的属性。

    import { reactive } from 'vue';  const state = reactive({  value: 0  
    });  // 正确的方式:修改对象的属性  
    state.value = 1;  // 错误的方式:重新赋值,这将导致失去响应性  
    // state = reactive({ value: 1 });
  2. 使用 Vue 3 的 Composition API 中的其他函数
    如果确实需要替换整个对象,并且希望新对象也是响应式的,可以考虑使用 ref(对于基本类型或对象引用)或再次调用 reactive(但通常不推荐这样做,因为它会绕过 Vue 的优化)。然而,对于对象来说,ref 并不直接适用,因为它会将对象作为单个响应式引用处理,而不是对象的每个属性。

    对于复杂情况,可能需要手动更新对象的属性,或者使用 Vue 3 提供的 toRefs 或 shallowReactive 等函数来辅助处理。

  3. 使用 shallowReactive
    如果你的对象结构很深,但你只需要浅层响应式(即只监听对象第一层属性的变化),可以使用 shallowReactive。然而,这并不会解决重新赋值后失去响应性的问题,只是改变了响应式跟踪的深度。

  4. 使用 Object.assign()

    1. 在 Vue 3 中,使用 Object.assign(state, { value: 1 }) 来更新一个由 reactive 包裹的对象 state,这种方法可以更新 state 对象的 value 属性,并且保持这个属性的响应性。但是,需要注意的是,这种方式并没有重新赋值给 state 本身,而是修改了 state 对象的属性。

      import { reactive } from 'vue';  const state = reactive({  value: 0  
      });  // 使用 Object.assign 更新 state 的 value 属性  
      Object.assign(state, { value: 1 });  //获取后端接口数据使用// 或者直接赋值,效果相同  
      // state.value = 1;  // 此时,如果视图中有依赖于 state.value 的部分,它将会更新

      object.assign-CSDN博客

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 面试金典题2.5
  • 【软件工程】需求分析概念
  • 【Delphi】Delphi 中的 LiveBindings 使用场景与概念
  • WPF 自定义路由事件
  • C++从入门到起飞之——多态 全方位剖析!
  • 普通程序员如何快速入门AIGC
  • C/C++内存管理 ——
  • 【WPF】桌面程序开发之窗口的用户控件详解
  • 医院信息化运维监控:确保医疗系统的稳定与安全
  • 运行WPS报错
  • 14年数据结构
  • Spring IoC DI
  • [图解]静态关系和动态关系
  • qt-C++笔记之作用等同的宏和关键字
  • 006——队列
  • 5、React组件事件详解
  • ES6简单总结(搭配简单的讲解和小案例)
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • Markdown 语法简单说明
  • Mocha测试初探
  • PHP CLI应用的调试原理
  • Python学习之路13-记分
  • Rancher-k8s加速安装文档
  • spring + angular 实现导出excel
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • WebSocket使用
  • 复杂数据处理
  • 猴子数据域名防封接口降低小说被封的风险
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 来,膜拜下android roadmap,强大的执行力
  • 前端相关框架总和
  • 前嗅ForeSpider中数据浏览界面介绍
  • 数据科学 第 3 章 11 字符串处理
  • 网页视频流m3u8/ts视频下载
  • 我的业余项目总结
  • 智能合约Solidity教程-事件和日志(一)
  • 走向全栈之MongoDB的使用
  • 国内开源镜像站点
  • ​1:1公有云能力整体输出,腾讯云“七剑”下云端
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (1) caustics\
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (35)远程识别(又称无人机识别)(二)
  • (AngularJS)Angular 控制器之间通信初探
  • (纯JS)图片裁剪
  • (待修改)PyG安装步骤
  • (二) 初入MySQL 【数据库管理】
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (生成器)yield与(迭代器)generator
  • (四)汇编语言——简单程序
  • (一)Docker基本介绍
  • (转)jdk与jre的区别
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .net连接oracle数据库