Reputation: 4895
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
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