概要
vue.jsのメソッドハンドラについて、@click="handler"
と書いても@click="handler()"
と書いても動くが、記述スタイルの違いだけではなく挙動に違いがあるから注意しよう、という話。
自分が書いているコードに@click="handler"
と@click="handler()"
が混在していたので,
@click="handler()"
に統一してみたところバグったのがきっかけ。
結論
イベントオブジェクトの取り扱い方が変わります。前者の場合はvueが用意してくれるので引数として使うことができますが、後者の場合は明示的に渡してあげる必要があります。
具体例
methods: {
handler: function (event) {
// 何らかの処理
}
}
としてイベントオブジェクトを使いたいとします
()なし
<div id="example">
<!-- ()なし -->
<button @click="handler">Click</button>
</div>
<script>
export default {
methods: {
handler: function (event) {
console.log(event)
}
}
}
</script>
問題なく動作します。
()あり
bad
<div id="example">
<!-- ()あり -->
<button @click="handler()">Click</button>
</div>
<script>
export default {
methods: {
handler: function (event) {
// eventがundefinedとなる
console.log(event)
}
}
}
</script>
イベントオブジェクトが渡されないのでうまくいきません。
※()をつける記法自体は間違いではありません。イベントオブジェクトが渡されなくなるだけです。
good
イベントオブジェクトを使いたい場合は特別な変数$event
を使って明示的に渡してあげる必要があります。
<div id="example">
<!-- $eventを明示的に渡す -->
<button @click="handler($event)">Click</button>
</div>
<script>
export default {
methods: {
handler: function (event) {
console.log(event)
}
}
}
</script>
$event
は何番目の引数でも問題ありません。
<div id="example">
<!-- $eventを明示的に渡す -->
<button @click="handler(arg1, $event, arg3)">Click</button>
</div>
<script>
export default {
methods: {
handler: function (arg1, event, arg3) {
console.log(event)
}
}
}
</script>
所感
個人的には、イベントオブジェクトを使うときは@click="handler($event)"
のように明示的に記載する方法に落ち着きました。
参考