目次
コンポーネントのカスタムイベントが動かない
ライブラリの記事を書いている時に、カスタムイベントが動作しない時があります。
ちょっと昔だったらバグだと思って記事を書くの止めて、別のライブラリの記事を書き出していました。
キャメルケースのイベント名が問題
最近は慣れて来たのか、問題にぶつかっても、ある程度対象法が分かるようになってきました。
今回のコンポーネントのカスタムイベントが動かない件について、Githubのソースコードを読みながら、なんとなくイベントの名が問題なんだろうなと気が付きました。
例えば以下のようなケースです。
イベント名をキャメルケースにします。
this.$emit('myEvent', ...arg)
一見すると問題無いようなキャメルケースの名前付けですが、この名前付けだとイベントが使用できないケースが発生します。
それはHTMLに直接カスタムタグを記載する場合です。
キャメルケース vs ケバブケース
以前、ブログでカスタムコンポーネントが表示されないというブログを書きました。
https://www.kabanoki.net/1385/
その時の原因は、
HTML の属性名は大文字小文字を区別せず、ブラウザは全ての大文字を小文字として解釈します。
でした。
対処法として、キャメルケースをケバブケースに変更することで対応することができました。
<blogPost>
↓
<blog-post>
プロパティなども同様の方法で対応することができます。
イベント名は小文字に自動変換されてしまう
カスタムタグやプロパティのようにキャメルケースをケバグケースにすることで対処できる場合もありますが、イベントの場合は別です。
イベントは、イベント名とイベントリスナ名を同じにする必要があります。
しかしHTML が大文字と小文字を判別しないためDOM テンプレート内の v-on イベントリスナは自動的に小文字に変換されます。
v-on:myEvent
は v-on:myevent
になります。
これでは動作する訳がありません。
Vue.jsのドキュメントにも同様の内容の記述がありました。
https://jp.vuejs.org/v2/guide/components-custom-events.html?#イベント名
動かない場合は別コンポーネントに取り込む
カスタムイベントがキャメルケースで使えないコンポーネントを、さらに別のコンポーネントに取り込むことで対応できる場合があります。
例えば、今調査をしている fullcalendar-vue ですが、カスタムイベントに @dateClick="myEvent"
というのがあります。
これが動かせずに四苦八苦していたのですが、別のコンポーネントに取り込むことで動作させることができました。
以下は一例です。
fullCalendarライブラリのコンポーネントを calender
というオリジナルのコンポーネントに取り込んでいます。
<div id="app"> <script type="text/x-template" id="calender"> <fullCalendar @dateClick="handleDateClick" ref="fullCalendar" default-view="dayGridMonth" :plugins="calendarPlugins" /> </script> <calender /> <div>
Vue.component('calender', { template: '#calender', data() { return { calendarPlugins: [ dayGridPlugin, FullCalendarInteraction ], } }, methods: { handleDateClick: function(info) { alert('click day :' + info.dateStr); }, } }); let app = new Vue({ el: '#app', });
これで動作させる事が可能です。
ライブラリではキャメルケースのカスタムイベントが結構ある
ライブラリの記事を書いていると、結構キャメルケースのイベント名を見かけます。
どれだけ有能なライブラリだとしても、キャメルケースが原因で使えないというケースが発生しています。
まとめ
- コンポーネントやプロパティはキャメルケースでも問題無い(ケバブケースで書くほうがより良い
- DOMのカスタムイベント名がキャメルケースだと動かないので、ケバブケースにする。
- キャメルケースのカスタムイベントも別のコンポーネントに取り込むと動かすことができるケースもある。(完全に対応できるかは不明
コンポーネントのカスタムイベントが動かない時の対処法でした。
今日はこの辺でー