[Vuejs]-How can I access the bound value of a <select>'s currently selected <option>?

0👍

While I still haven’t found an exact solution to my original question, I’ve found a design pattern that I think solves the issue satisfactorily. By using a computed property with a getter and setter, I can use v-model on the <select> without needing watchers or any internal component state.

Vue.component('custom-select', {
  template: '#component',
  props: ['options', 'value'],
  computed: {
    valueProxy: {
      get() {
        return this.value;
      },
      set(newValue) {
        this.$emit('input', newValue);
      },
    },
  },
});
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

<script type="text/x-template" id="component">
  <div id="component">
    <select v-model="valueProxy">
      <option v-for='option in options' :value="option">
        <slot v-bind="{ option }"></slot>
      </option>
    </select>
  </div>
</script>

0👍

Let’s say options prop is an array of object as below
You can change the event emitter of child component to return object instead of string like this:

<style>
  [v-cloak] {
    display: none;
  }
</style>
<!-- // App -->
<div id="app">
  <div v-cloak>
    Value in parent: {{selectedValue}}
    <br><br>
    <custom-select :options='selectOptions' v-model='selectedValue'></custom-select>
  </div>
</div>

<!-- // JS Code -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

<script type="text/x-template" id="component">
  <div id="component">
    <select @change="$emit('input', options.find(option => option.value == $event.target.value))">
      <option v-for='option in options' :value="option.value">
        {{ option.text }}
      </option>
    </select>
  </div>
</script>
<script>
  // Mount App
  new Vue({
    el: '#app',
    data() {
      return {
        selectOptions: [
          { text: 'Apple', value: 'apple', price: '10' },
          { text: 'Banana', value: 'banana', price: '20' },
          { text: 'Strawberry', value: 'strawberry', price: '30' },
        ],
        selectedValue: {}
      }
    },
    // Custom component
    components: {
      'custom-select': Vue.component('custom-select', {
        template: '#component',
        props: ['options', 'value'],
      })
    }
  })
</script>

Leave a comment