Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

vuejs reactivity with variable initiated in mounted function

I have a dynamic component building multiple select, the template :

<template>
  <div>
    <b-field
      v-for="(key,index) in allSelects"
      :key="index"
      :label="key"
    >
      <b-select
        :placeholder="key"
        v-model="values[key]"
      >
        <option
          v-for="(value,index) in optionsValues(key)"
          :key="index"
          :value="value"
        >
          {{ value }}
        </option>
      </b-select>
    </b-field>
  </div>
</template>

and the script is

<script>
export default {
  name: 'Test',
  data () {
    return {
      allSelects: ['select1', 'select2'],
      values: {}
    }
  },
  computed: {
    optionsValues: function () {
      return key => { return this.getData(key) }
    }
  },
  methods: {
    getData: function (key) {
      if (key === 'select1') {
        return ['valA', 'valB', 'valC', 'valD']
      } else {
        if (this.values.select1 === 'valA') {
          return ['A', 'AA', 'AAA', 'AAAA', 'AAAAA']
        } else if (this.values.select1 === 'valB') {
          return ['B', 'BB', 'BBB', 'BBBB', 'BBBBB']
        } else if (this.values.select1 === 'valC') {
          return ['C', 'CC', 'CCC', 'CCCC', 'CCCCC']
        } else {
          return ['D', 'DD', 'DDD', 'DDDD', 'DDDDD']
        }
      }
    }
  },
  mounted () {
    // code
  }
}
</script>

In the mounted function, if I define the code as :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  mounted () {
    this.values = {
      select1: null,
      select2: null
    }
  }

Everything is working juste fine, the values of select1 change the values of select2, but if I dynamically build it as following :

  mounted () {
    for (let val of this.allSelects) {
      this.values[val] = null
    }
  }

it’s no longer working ! I would like it to be dynamic, the content of allSelects is dynamic in my real component. What would be the best solution ?

>Solution :

You are using Vue 2, aren’t you? To add a reactive property to an object in Vue 2 you have to set it with Vue.set() (see documentation). So this should work:

  mounted () {
    for (let val of this.allSelects) {
      Vue.set(this.values, val, null)
    }
  }

Alternatively, you can initialize the object with the desired structure:

const selectIds = ['select1', 'select2']
export default {
  name: 'Test',
  data () {
    return {
      allSelects: selectIds.reduce( (s, i) => ({...s, [i]: null}), {}),
      values: selectIds,
    }
  },
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading