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

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博客


http://www.kler.cn/a/317702.html

相关文章:

  • 第12章 系统部署
  • 随机数
  • 微服务day08
  • react-redux useSelector钩子 学习样例 + 详细解析
  • 【IC每日一题:IC常用模块--RR/handshake/gray2bin】
  • Linux screen和cscope工具使用总结
  • C#控件开发能够阅读的书籍
  • ESP8266+DHT11+Python制作一个物联网温湿度传感器
  • 基于C#+SQL Server2005(WinForm)图书管理系统
  • 多边形抠图 python
  • python爬虫案例——抓取链家租房信息
  • IPsec-Vpn
  • 6、论文阅读:水下图像增强基准数据集及其他数据集
  • 【Godot4.3】三角形类
  • lunar无第三方依赖的公历、农历、法定节假日...日历工具库
  • 什么是单例模式?
  • 用最新的C++技术,如何实现一个序列化工具库?
  • CSS的盒子模型(Box Model)
  • 2024年最强网络安全学习路线,详细到直接上清华的教材!
  • sftp上传文件报错提示“Permission denied“
  • geodatatool(地图资源下载工具)3.8更新
  • JavaScript 网页设计案例详解( 最新技术趋势)
  • jmeter本身常用性能优化方法
  • JavaWeb校园二手交易平台
  • 统信服务器操作系统【qcow2 镜像空间扩容】方案
  • Stable Diffusion Fooocus批量绘图脚本