'How to I make the select drop down show the currently selected value in Vue?

Similar to Select always first value select vue.js but I am making a custom component.

I have an SFC with a few extra debug output

<script>
export default {
  props: ['modelValue', 'options'],
  emits: ['update:modelValue']
}
</script>

<template>
  <div>
    
  <select
    :value="modelValue"
    @change="$emit('update:modelValue', JSON.parse($event.target.value))"
  >
    <option value="" disabled>no selection</option>
    <option v-for="option in options" :value="JSON.stringify(option)" :selected="JSON.stringify(modelValue) === JSON.stringify(option)">X{{JSON.stringify(option)}}X{{JSON.stringify(modelValue) === JSON.stringify(option)}}</option>
  </select>
     {{modelValue}}
  </div>
</template>

And a calling component

<script>
import CustomInput from './CustomInput.vue'

export default {
  components: { CustomInput },
  data() {
    return {
      message: '',
      blah: [
        {a:"a"},
        {b:2},
        {c:{d:1}},
      ]
    }
  },
  computed: {
        theMessage() {
      return JSON.stringify(this.message);
    }
}
}
</script>

<template>
  <CustomInput v-model="message" :options="blah"/> {{ theMessage }}
</template>

But I am not able to get the selected item to appear in the dropdown even if the "label" is showing it should be selected.

Playground



Solution 1:[1]

You can use v-model in your child component and bubble the event to parent with computed setter/getter

App.vue

<script>
import CustomInput from './CustomInput.vue'

export default {
  components: { CustomInput },
  data() {
    return {
      message: '',
      blah: [
        {a:"a"},
        {b:2},
        {c:{d:1}},
      ]
    }
  },
}
</script>

<template>
  <CustomInput v-model="message" :options="blah" /> {{ message }}
</template>

CustomInput.vue

<script>
export default {
  props: ['modelValue', 'options'],
  emits: ['update:modelValue'],
  computed: {
    internalValue: {
      get() {
        return this.modelValue;
      },
      set(newVal) {
        this.$emit('update:modelValue', newVal)
      }
    }
  }
}
</script>

<template>
  <div>
  <select

        v-model="internalValue"
  >
    <option value="" disabled>no selection</option>
    <option v-for="option in options" :value="JSON.stringify(option)" :selected="JSON.stringify(modelValue) === JSON.stringify(option)">{{
      option}}</option>
  </select>
  </div>
</template>

(I'm not sure your JSON.stringy is usefull)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1