次のコードを使ってVue.jsのイベント処理を試します。
<template>
<ul>
<li v-for="(item, idx) in items" :key="idx">
<label>
<input type="checkbox" v-model="item.checked" @click="clicked(item)">
{{item.name}}
</label>
</li>
</ul>
</template>
<script>
export default {
data() {
return {
items: [
{ name: 'foo', checked: true },
{ name: 'bar', checked: false },
{ name: 'baz', checked: false }
]
};
},
methods: {
clicked(item) {
console.log("clicked");
console.log(item.checked);
}
}
}
</script>
チェックされていないチェックボックスをクリックすると、item.checkedはfalseとなります。あれ?チェックしたんだからtrueになるはずでは。
clicked
false
Eventオブジェクトを使ってHTML要素を見てみます。
<input type="checkbox" v-model="item.checked" @click="clicked($event, item)">
clicked(event, item) {
console.log("clicked");
console.log(item.checked);
console.log(event.target.checked);
}
チェックボックスはチェックされているけど、dataのオブジェクトにはまだ反映されていないようです。
clicked
false
true
ならば、nextTickを使えば反映されるのでは、と思いきやfalseのままです。
clicked(item) {
console.log("clicked");
this.$nextTick(() => {
console.log(item.checked);
});
}
以上の挙動は、inputイベントを使っても同じです。正解は、clickでもinputでもなくchangeイベントを使うことでした。
<input type="checkbox" v-model="item.checked" @change="changed(item)">
changed(item) {
console.log("changed");
console.log(item.checked);
}
参考: vue.js - Vuejs click event from checkbox? - Stack Overflow