[Vuejs]-Vue v-for after condition using vuex

3👍

You should create a computed property which returns model options based on the value of the selected make type. Then you can bind to that and it will automatically update whenever the selected make changes:

models() {
  if (this.selectedType) {
    return this.cars.make.find((car) => car.carid === this.selectedType).models;
  }
}

Here’s a working example:

const store = new Vuex.Store({
  state: {
    cars: {
      make: [{
        name: 'Audi',
        carid: '1',
        models: [
          { modelid: '1.1', name: 'A7' },
          { modelid: '1.2', name: 'A8' },
        ]
      }, {
        name: 'BMW',
        carid: '2',
        models: [
          { modelid: '2.1', name: '5 Series' },
          { modelid: '2.2', name: '7 Series' }
        ],
      }]
    }
  }
})


new Vue({
  el: '#app',
  store,
  data() {
    return {
      selectedType: '',
    };
  },
  computed: {
    ...Vuex.mapState(['cars']),
    models() {
      if (this.selectedType) {
        return this.cars.make.find((car) => car.carid === this.selectedType).models;
      }
    }
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.min.js"></script>
<div id="app">
  <h4>Car make:</h4>
  <select v-model="selectedType" name="carmake" required>
    <option value=""></option>
    <option  v-for="(cars, index) in cars.make" :key="index" :value="cars.carid">{{ cars.name }}</option>
  </select>

  <h4>Car model:</h4>
  <select>
    <option value=""></option>
    <option v-for="(model, index) in models" :key="index" :value="model.modelid">{{ model.name }}</option>
  </select>
</div>

2👍

Working example with your data:

const state = {
  make: [
    {
      name: 'Audi',
      carid: '1',
      models: [
       {modelid: '1.1', name: 'A7'},
       {modelid: '1.2', name: 'A8'}
      ]
    }, {
      name: 'BMW',
      carid: '2',
      models: [
        {modelid: '2.1',  name: '5 Series'},
        {modelid: '2.2',  name: '7 Series'}
      ]
    }
  ]
}

new Vue({
  el: '#app',
  data: {
    state: state,
    selected: 0
  },
  computed: {
    models () {
      var maker = this.state.make.find(m => m.carid === this.selected)
      return maker ? maker.models : []
    }
  }
})
<div id="app">
  <select v-model="selected">
    <option value="0" selected>Choose maker</option>
    <option
      v-for="maker in state.make"
      :key="maker.carid"
      :value="maker.carid"
    >{{ maker.name }}</option>
  </select>
  <br>
  <select>
    <option value="0" selected>Select model</option>
    <option
      v-for="model in models"
      :key="model.modelid"
      :value="model.modelid"
    >{{ model.name }}</option>
  </select>
</div>

<script src="https://unpkg.com/vue@2.5.3/dist/vue.min.js"></script>

If you can, change ‘modelid’ to simple integers – 1, 2, etc., at least. And if you can and you know how to do it, change your data structure – divide makers and models to separate arrays/objects.

1👍

Here’s a plugin for this specific task you’re trying to accomplish: vue-dependon.

It hasn’t been updated for 1-2years, but I think that you can check its source code and see how it works.

UPDATE:
All you need from the sourcecode is the loadOptions function and the code between L83 and L105.
You can adapt that code to your needs.

Leave a comment