Reputation: 3343
My component would like to add a new reactive-array field to the SST (vuex). I tried in beforeCreate hook, but the added array is not reactive; it's just a plain JS array.
Note that this is not the same as adding/removing elements from an existing array created at the Vue's initialization time. Such arrays are "wrapped" and become reactive as expected, mindful of "Array Change Detection" gotchas.
In my case, I'm trying to dynamically add an entirely new field of array type to the SST and make it reactive at the same time. Possible?
Upvotes: 9
Views: 7778
Reputation: 135762
Have a look at Reactivity in Depth - Change Detection Caveats:
Change Detection Caveats
Due to the limitations of modern JavaScript, Vue cannot detect property addition or deletion. Since Vue performs the getter/setter conversion process during instance initialization, a property must be present in the
data
object in order for Vue to convert it and make it reactive.
But you say you are adding an array dynamically:
I'm trying to dynamically add an entirely new field of array type to the SST and make it reactive at the same time. Possible?
From the docs (bold is mine):
Vue does not allow dynamically adding new root-level reactive properties to an already created instance. However, it’s possible to add reactive properties to a nested object using the
Vue.set(object, key, value)
method:
Vue.set(vm.someObject, 'myArrayName', [1,2,3]);
Which should help you making your array reactive.
Upvotes: 7
Reputation: 2413
I see two problems here:
I've initiate array if not exist in add method because when I'm receiving data from server myArray is not exist.
My solutuion below:
myVuexArray.js
import Vue from 'vue'
const state = {
myObject: {
myArray: [],
}
}
const getters = {
getMyArray: state => {
return state.myObject.myArray;
}
}
const mutations = {
addElementToArray(state, value) {
if (state.myObject.myArray === null || state.myObject.myArray === undefined || state.myObject.myArray === '') {
// initiate array
state.myObject.myArray = [];
}
// add new element to array
Vue.set(
state.myObject.myArray,
state.myObject.myArray.length,
value
);
// creates a new array everytime this solves the reactivity issue
Vue.set(state, 'myObject.myArray', state.myObject.myArray);
return state.myObject.myArray;
},
removeElementFromArray(state, index) {
state.myObject.myArray.splice(index, 1);
}
}
export default {
state,
mutations,
getters
}
Best regards
Upvotes: 1
Reputation: 462
Dynamic module registration could help you to achieve this : https://vuex.vuejs.org/en/modules.html
This would allow you to dynamically register a new module containing your array field in the beforeCreate hook.
Upvotes: 0