Как я уже упоминал в комментарии выше, вы, по сути, делаете все правильно, но передаете некоторые аргументы методу select, который вам на самом деле не нужен.В случае события change элемента select в вашем компоненте вам не нужно ничего передавать, поскольку объект event
будет автоматически передан, если вы просто укажете функцию.
В вашем шаблоне:
<select :value="value" @change="select">
И ваш обработчик событий:
select(evt) {
this.$emit('input', evt.target.value);
}
const Selectbox = {
props: {
value: String
},
methods: {
select(evt) {
this.$emit('input', evt.target.value);
}
},
template: `
<div>
<select :value="value" @change="select">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<div>The value is {{ value }}.</div>
</div>`
};
new Vue({
el: "#app",
components: { Selectbox },
data: () => ({
selectboxValue: 1
}),
template: `
<div>
<selectbox v-model="selectboxValue" />
</div>
`
})
body {
padding: 50px;
}
label {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
</div>
Что я обычно люблю делать для таких компонентов ввода, так это просто использовать вычисляемое свойство в качестве модели для внутреннего компонента.
<select v-model="selected">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
И вычисляется так:
computed:{
selected:{
get() {return this.value},
set(v) {this.$emit('input', v)}
}
},
const Selectbox = {
props: {
value: String
},
computed:{
selected:{
get() {return this.value},
set(v) {this.$emit('input', v)}
}
},
template: `
<div>
<select v-model="selected">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<div>The value is {{ value }}.</div>
</div>`
};
new Vue({
el: "#app",
components: { Selectbox },
data: () => ({
selectboxValue: 1
}),
template: `
<div>
<selectbox v-model="selectboxValue" />
</div>
`
})
body {
padding: 50px;
}
label {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
</div>