🐕

@vue/compatによりVue2モードで動いていたアプリケーションをVue3モードに変更した際に詰まった問題(`.native`)

2023/10/03に公開

はじめに

2年ほど前に移行ビルドを使ってVue2からVue3にマイグレーションしました。しかしそれ以来そのままになっており、また他のライブラリを使ってる上で不具合が見受けられる(例:ElementPlusのel-tagのxアイコンが動作しない、etc..)ことから、流石にそろそろ標準ビルドへの切り替え(=完全移行)を決意しました。

手順としては以下で進めました。

  1. 移行ビルドのモードを3に切り替えてエラー箇所の対応
  2. 移行ビルドの削除

今回は手順1において遭遇したとあるbreaking changes問題について取り上げます

Vue.configureCompat({
+ MODE: 3,
- WATCH_ARRAY: false,
- COMPONENT_V_MODEL: false,
- ...
})

emit名にDOMネイティブに存在するイベントキーを使っている

「らくしふ」には、以下のような表示項目の表示・非表示を切り替える画面がありますが、動作しなくなりました。

2回emitされている?なぜかDOMネイティブなEventオブジェクトも渡されている・・・。

なんでやねんということで調べていると参考になる記事が2つヒット。
https://github.com/vuejs/core/issues/4566#issuecomment-917997056
https://zenn.dev/karino_m/articles/vue-dom-native-event-key-name-emit

つまりv-on.native modifier removedの影響だそうです

The .native modifier for v-on has been removed. At the same time, the new emits option allows the child to define which events it does indeed emit.
Consequently, Vue will now add all event listeners that are not defined as component-emitted events in the child as native event listeners to the child's root element

タイトルから.nativeが使えなくなるのはわかるが、それ以外にemitの仕様が変わってることなんて読み取れるかよぉって言いたいところです...。うぐぐぅ・・・。

結論

DOMネイティブに存在するイベントキーをemit名として利用しているとコンポーネントでは、emitsオプションを明示的に指定しましょう。ってか子コンポーネントでemit使う場合は、emitオプション指定は必須の運用で良さそうですね

props: {...},
+ emits: ["change"],
setup() {
  ...
クロスビットテックブログ

Discussion