Vue 3における以下の警告について原因と解決策を提示する。
Extraneous non-emits event listeners (emitFunc) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. If the listener is intended to be a component custom event listener only, declare it using the “emits” option.
警告の内容と原因
内容
runtime-core.esm-bundler.js:38 [Vue warn]: Extraneous non-emits event listeners (emitFunc) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. If the listener is intended to be a component custom event listener only, declare it using the "emits" option.
この警告は、特定のカスタムイベントリスナ(このケースではemitFunc
)がコンポーネントに渡されているが、それらが自動的に継承できないと言っている。
原因
「自動的に継承できない」という状況は主に、コンポーネントが「複数のルート要素またはテキストをルートノードとしてレンダリングする場合」に発生する。
以下のような構成。今回、この構成が問題だった。
<template>
<custom-primary-component @emitFunc="emitFunc" />
<custom-secondary-component />
</template>
この警告が発生する主な原因は、Vue.js 3ではフラグメント(複数のルート要素)を持つことが許されているためである。しかし、複数のルート要素がある場合、どの要素にイベントリスナーを適用すればいいのかが曖昧になるため、このような警告が発生する。
参照(Vue 3 移行ガイド): Fragments
解決策
方法は2つある。
- イベントを
emits
オプションで明示的に宣言する - 単一のルート要素を持つようにコンポーネントをリファクタリングする
1. イベントをemits
オプションで明示的に宣言する
emits
オプションでイベントを宣言することで、Vue.jsにこのイベントがカスタムイベントであると明示的に伝え、警告を消すことができる。
<template>
<custom-primary-component @emitFunc="emitFunc" />
<custom-secondary-component />
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
// emitsオプションで明示的に宣言する
emits: ['emitFunc'],
components: {
CustomPrimaryComponent,
CustomSecondaryComponent
},
})
</script>
参照: emits
setup構文の場合は以下のように書ける。
<script setup>
defineEmits(['emitFunc'])
</script>
参照: defineProps() & defineEmits()
2. 単一のルート要素を持つようにコンポーネントをリファクタリングする
<template>
<div class="single-root">
<custom-primary-component @emitFunc="emitFunc" />
<custom-secondary-component />
</div>
</template>
このようにすると、全体がdiv.single-root
という1つのルート要素によって囲まれ、問題が解決される可能性がある。これで、任意のイベントリスナやプロパティがこの単一のルート要素に適用される。
この記事は役に立ちましたか?
もし参考になりましたら、下記のボタンで教えてください。
コメント