0

I am trying to remember how to return the value within the select from a component.

Despite I bet is pretty easy I forgot or I am just doing it wrong.

I call the component:

<custom-select :options="options" v-model="selectedMain"></custom-select>

And then I have the component itself:

<template>
    <fieldset class="form-group">
        <select v-model="selected" 
                id="something" 
                name="something">
            <option :value="null">Select an option</option>
            <option v-for="option in options" 
                    value="option.id"
                    v-html="option.name"></option>
        </select>
    </fieldset>
</template>
<script>
    module.exports = {
        props: [ 'options' ],
        data: function() {
            return {
                selected: null
            }
        }
    }
</script>

This is defined in my main Vue instance of course and it renders ok:

new Vue({
    ...
    data: function() {
        return {
            ...
            selectedMain: null
            ...
        }
    },
    ...
})

But when I change the value to 1 (for instance) from the dropdown I can see in the Vue Debugger toolbar that:

<Root>
    selectedMain: null
    <CustomSelect>
        selected: 1
    </CustomSelect>
</Root>

Edit 1: I think this is pretty the same thing:

Vue.component('custom-select', {
  data () {
    return {
      selected: null
    }
  },
  props: [ 'options' ],
  template: `<fieldset class="form-group">
        <select v-model="selected"
                id="something"
                name="something">
            <option :value="null">Select an option</option>
            <option v-for="option in options"
                    value="option.id"
                    v-html="option.name"></option>
        </select>
    </fieldset>`
});

new Vue({
  el: '#app',
  data: function() {
    return {
      options: [
        { id: 1, name: "First option" },
        { id: 2, name: "Second option" },
        { id: 3, name: "Third option" },
      ],
      selectedMain: null
    }
  },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>

<div id="app">
  <custom-select :options="options" v-model="selectedMain"></custom-select>
  <p>Selected Main: {{ selectedMain }}</p>
</div>

Therefore I want obviously selectedMain takes the selected value.

How to achieve this? Any suggestions are appreciated.

2 Answers 2

1

You need to make your own component able to emit change, and bind vaue. By default v-model binds to :value and @change and @input events but you can customize it.

In custom select component you need something like:

module.exports = {
    model: {
        prop: 'value',
        event: 'change'
    },
    props: [ 'options', 'value' ],
    data: function() {
        return {
            internal: null
        }
    },
    computed: {
        selected: {
            get() { return this.internal },
            set(val) {
               this.$emit('change', val)
            }
        }
    }
    watch: {
        value(newVal) {
            this.internal = newVal
        }
    }

}

If it's as simple as your code above (but I doubt it) the implementation can even be simpler (all done in the template):

https://v2.vuejs.org/v2/guide/components-custom-events.html#Customizing-Component-v-model

Vue.component('base-checkbox', {
model: {
    prop: 'checked',
    event: 'change'
},
props: {
    checked: Boolean
},
template: `
    <input
    type="checkbox"
    v-bind:checked="checked"
    v-on:change="$emit('change', $event.target.checked)"
    >
`
})

Which you'd use in the parent template as:

<base-checkbox v-model="lovingVue"></base-checkbox>
Sign up to request clarification or add additional context in comments.

Comments

0

Vue has one-way data flow.

You can use an event bus or state manager like vuex to guide a change in child element to a global state.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.