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>