9

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?

4
  • 1
    How exactly are you adding the new field of array type? Can you show some code? Also, are you aware of Vue.set()? Commented Feb 23, 2018 at 14:23
  • Thanks a lot - I tried this.$set but didn't get the expected result - but now I'm doubting myself if I did use it right;Vue.set worked. Commented Feb 23, 2018 at 14:58
  • I added an answer referring to the docs. See if it matched your problem. Commented Feb 23, 2018 at 15:14
  • It did & and gave you the rightful credit. Thanks for helping. Commented Feb 23, 2018 at 15:54

3 Answers 3

7

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.

Sign up to request clarification or add additional context in comments.

1 Comment

1

I see two problems here:

  1. add dynamically array using vuex.
  2. add dynamically element to this array and render this element.

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

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.