自学内容网 自学内容网

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


原文地址:https://blog.csdn.net/H2608520347/article/details/142447577

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!