Событие, которое вызывается на <select>
при выборе уже выбранного <option>
, равно mouseup
.
Следовательно, вам понадобится дополнительная опора для хранения состояния выбора (isOpen
). Вы будете вызывать вспомогательный метод (назовем его mouseUp
) и вызывать handler()
только тогда, когда выбор закрывается.
Для всех остальных случаев ввода (нажатие клавиш и еще много чего) используйте @input
.
Я добавил еще одну вспомогательную опору, чтобы дважды не вызывать handler()
:
Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: () => ({
data: 1,
isOpen: false,
changed: false
}),
methods: {
mouseUp(e) {
if (this.isOpen) {
this.$nextTick().then(() => {
if (!this.changed){
this.handler(e);
}
});
this.isOpen = false;
} else {
this.changed = false;
this.isOpen = true;
}
},
handler(e) {
this.changed = true;
console.log(`handler(${e.target.value})`);
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<select v-model="data" @mouseup="mouseUp" @input="handler">
<option>1</option>
<option>2</option>
<option>3</option>
</select>
</div>
Логика может показаться громоздкой, но, поскольку @input
срабатывает до @mouseup
, я звоню handler()
из mouseUp()
, только если @input
не было запущено и <select>
закрывается.
Единственный случай, когда <select>
закрывается и handler()
не срабатывает, - это нажатие клавиши ESC, когда выбор открыт. Но я не уверен, что вам следует звонить в этом случае (пользователь хочет отменить любое изменение). Если вы хотите позвонить и в этом случае, прослушать этот конкретный случай довольно просто.