Home > Enterprise >  How to set reactive object in Vuejs 3
How to set reactive object in Vuejs 3

Time:04-15

I have a reactive object in the global space:

let cart = Vue.reactive({
    order: {
       itemsCount: 0
    },
    items: []
});

It works great. When we change this cart in any way (for example cart.order.itemsCount = 1;) other UI parts get updated automatically.

But if we set it to a new object (let's say we have received a new order object from server) then it breaks and won't work anymore:

cart = serverCart

We even tried cart = Vue.reactive(serverCart) and it still does not cause other UI parts to re-render.

It's possible that we set every property manaully:

cart.order.itemsCount = serverCart.order.ItemsCount;
cart.items[0].productTitle = serverCart.order[0].productTitle;
...

But this is idiotic of course.

How can we re-set a reactive object entirely in Vue.js 3?

Update:

You can see this codesandbox in action.

CodePudding user response:

For setting new values reactive objects in vue3, you need to use Object.assign function and you should not reassign it

Here is an example:

<template>
  {{ reactiveTest }}
  <button @click="change">Change</button>
</template>

<script>
import { reactive } from "vue";
export default {
  setup() {
    let reactiveTest = reactive({
      a: 1,
      b: 2,
    });
    function change() {
      const serverReactive = {
        a: 3,
        b: 4,
      };
      // reactiveTest = serverReactive;  Do not do this
      Object.assign(reactiveTest, serverReactive)
    }
    return {
      reactiveTest,
      change,
    };
  },
};
</script>

CodePudding user response:

You are trying to copy by reference, try to copy by value with spread operator ... :

const { reactive } = Vue
const app = Vue.createApp({
  el: "#demo",
  setup() {
    let cart = reactive({
      order: {
         itemsCount: 0
      },
      items: []
    });
    
    const someCart = {order: {itemsCount: 3}, items: [{id: 1, name: "aaa"}, {id: 2, name: "bbb"}, {id: 3, name: "444"}]}
    
    cart = reactive({...someCart})
    
    return {cart }
  }
})
app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
    <p> {{ cart }}</p>
    <label>change items count</label>
    <input type="number" v-model="cart.order.itemsCount" />
</div>

  • Related