I am trying to display the select drop down using vs-select, the options are taken from the API. Here is my scenario I have made all my components dynamic, i have 3 cards in my front page, if I click any of the card respective contents are displayed.

Here is the response that I get from the /my-project endpoint:

    [
          {
            "uid": 1,
            "choice": "project_title1|project_title2|project_title3",
            "age": "35",
            "country": "india"
          },
          {
            "uid": 2,
            "choice": "project_title2",
            "age": "25",
            "country": "australia"
          } 
          ...
    ]

Here is my code:

        <span v-if="out.choice">
            <template  v-for="(val, e) in Myfilter(out.choice)">
                <vs-select v-model="check" :key="e" :options="[{label: val}]" />
            </template>
        </span>
        <div v-if="out.choice === 'project_title1'">     
           --show contents1--
        </div>
        <div v-if="out.choice === 'project_title2'">
           --show contents2--
        </div>
    check: null,
    out: null
    // ...
    methods: {
      Myfilter (val){
      return val.replaceAll('_', ' ').split('|')
    },
      SelectVue (id) {
          this.$http.get(`/my-project/${id}`)
            .then((res) => {this.out= res.data})
        }
      },
    mounted (){
      this.SelectVue (this.$route.params.uid)
    }

If the user clicks on 2nd card he will get the details of uid=2 i.e in vue-select he will get the option as project title2. If the user clicks on 1st card he will get the details of uid=1 then three vue-select are displayed as shown in image:

enter image description here

Rather i want a single vue-select and three different options in it as:

enter image description here

Here is my question: How do i have a single vue-select for the data coming from API and then display different options for it.

1

There are 1 best solutions below

8
On BEST ANSWER

In order to save the selection you have to map an additional property to each of your API entries. I called it selection in the following example. I also made a computed extracting the user selection from entries.

Note I also named choice in each item to choices (makes more sense to me).

Vue.config.productionTip = false;
Vue.config.devtools = false;
new Vue({
  el: '#app',
  data: () => ({
    entries: [{
        "uid": 1,
        "choices": "project_title1|project_title2|project_title3",
        "age": "35",
        "country": "india"
      },
      {
        "uid": 2,
        "choices": "project_title2",
        "age": "25",
        "country": "australia"
      }
    ].map(el => ({...el, selection: null }))
/* Entries need to have a `selection` with a value other than `undefined` before 
 * being passed to Vue's data. Otherwise `.selection` on each won't be reactive
 */
  }),
  computed: {
    selection() {
      return Object.assign({}, ...this.entries.map(e => ({
        [e.country]: e.selection
      })));
    }
  },
  methods: {
    makeSelectOptions(choices) {
      return choices.split('|').map(value => ({
        text: value,
        value
      }))
    }
  }
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuesax.umd.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/vuesax/dist/vuesax.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/material-design-icons/3.0.2/iconfont/material-icons.min.css" rel="stylesheet"/>

<div id="app">
  <div v-for="(entry, index) in entries">
    <vs-select :label="entry.country"
               v-model="entry.selection">
      <vs-select-item :key="index"
                      v-bind="item"
                      v-for="(item,index) in makeSelectOptions(entry.choices)" />
    </vs-select>
  </div>
  <pre v-text="selection"></pre>
</div>

Turning choices into selection options is handled by the makeSelectOptions method.