Martyn Ball
Martyn Ball

Reputation: 4895

Vue: Return select value from component back to parent component

I can't figure this out. I have got a component StockSearch.vue, within this component I have got another component called StockSearchSelect.vue. Code is below.

I want to change the selected value within the makes object within StockSearch when the selected option is changed within the StockSerchSelect component. How do I do this?

StockSearch.vue

<template>

    <div class="flex flex-col lg:flex-row">
        <search-select title="Make" :options="data.makes"></search-select>
        <search-select title="Model" :options="data.makes"></search-select>
        <search-select title="Variant" :options="data.makes"></search-select>
        <search-select title="Trim" :options="data.makes"></search-select>
        <search-select title="Bodystyle" :options="data.makes"></search-select>
        <search-select title="Transmission" :options="data.makes"></search-select>
        <search-select title="Doors" :options="data.makes"></search-select>      
    </div>

</template>
<script>
import SearchSelect from './StockSearchSelect';
export default {
    components: {
        SearchSelect
    },
    data: function() {
        return {
            data: {
                makes: {
                    options: [
                        { code: 1, display: 'Audi' },
                        { code: 2, display: 'BMW' },
                        { code: 3, display: 'Chevrolet' },
                        { code: 4, display: 'Mercedes Benz' },
                        { code: 5, display: 'Suzuki' },
                        { code: 6, display: 'Volvo' },
                        { code: 7, display: 'Lamborghini' },
                        { code: 8, display: 'Citron' },
                        { code: 9, display: 'Jeep' },
                    ],
                    selected: null
                }
            }
        }
    },
    watch: {
        data: {
            deep: true,
            handler: function(data) {
                console.log(data);

            }
        }
    }
}
</script>

StockSearchSelect.vue

<template>
    <div class="w-full p-2">
        <label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-state">{{ title }}</label>
        <div class="relative">
            <select class="block appearance-none w-full bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500" id="grid-state" v-model="selected">
                <option value="">Any {{ title }}</option>
                <option v-for="(value, index) in data.options" :key="index" :value="value.code">{{ value.display }}</option>
            </select>
            <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
                <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/></svg>
            </div>
        </div>
    </div>
</template>
<script>
export default {
    props: {
        title: String,
        options: Array,
        selected: Int
    },
    data: function() {
        return {
            selected: null
        }
    },
    watch: {
        selected: function(value) {

        }
    }
}
</script>

Upvotes: 0

Views: 537

Answers (1)

Shoejep
Shoejep

Reputation: 4849

If you only want to update the makes object when an option is changed, all you need to do is $emit an event when the value changes and then listen for the event in the parent component. You should probably read the props and custom events documentation.

You could change the below select to include @input='$emit("selected", $event.target.value)'

<select class="block appearance-none w-full bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500" id="grid-state" v-model="selected" @input='$emit("selected", $event.target.value)'>
    <option value="">Any {{ title }}</option>
    <option v-for="(value, index) in data.options" :key="index" :value="value.code">{{ value.display }}</option>
</select>

and then add @selected="data.makes.selected = $event" to the below component.

<search-select title="Doors" :options="data.makes" @selected="data.makes.selected = $event"></search-select>      

I've also added a working snippet below in case that helps.

Vue.component("my-select", {
  template: "<select @input='$emit(`selected`, $event.target.value)'><option selected>Please Select</option><option value='1'>1</option><option value='2'>2</option></select>"

});

new Vue({
  el: "#app",
  data: () => {
    return {
      selectedValue: null
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div>
    <my-select @selected="selectedValue = $event"></my-select>
    {{selectedValue}}
  </div>
</div>

Upvotes: 1

Related Questions