Extraneous non-emits event listeners (getModalBtn) 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.
警告提示是因为 Vue 3 在处理自定义事件时,会对传递到子组件的事件进行验证,如果子组件是一个“片段”或者根节点是文本节点,Vue 无法自动继承事件监听器。
在我的代码中,父组件在 <Exchange>
组件上监听了 getModalBtn
事件,但 Vue 认为你没有在子组件中明确声明这个事件。
解决方法
在子组件中,你需要通过 emits
选项显式声明 getModalBtn
事件,这样 Vue 就知道这个事件是允许的,并且不会显示警告。
子组件代码:
<template>
<view class="exchange-btn" @click="getModalBtn">
<!-- 按钮插槽 -->
<slot name="modalBtn"> </slot>
</view>
</view>
</template>
<script>
export default {
emits: ['getModalBtn'], // 解决办法:显式声明 getModalBtn 事件
data(){
gold: 100,
diamonds: 200,
},
methods: {
getModalBtn() {
const params = {gold:this.gold,diamonds:this.diamonds}
this.$emit('getModalBtn',params ); // 触发事件
},
},
};
</script>
父组件代码:
<template>
<Exchange ref="exchangePage" @getModalBtn="getExchangeBtn">
<template #modalBtn>
<view class="tabPage-btn">
<button @click="getExchangeBtn">{{$t('tab1')}}-new</button>
</view>
</template>
</Exchange>
</template>
<script>
import Exchange from './Exchange.vue';
export default {
components: {
Exchange,
},
data() {
return {
gold: 0,
diamonds: 0,
isExchange: false,
};
},
methods: {
getExchangeBtn(event) {
this.gold = event.gold;//100
this.diamonds= event.diamonds;//200
this.isExchange = true;
},
},
};
</script>
解释
emits: ['getModalBtn']
:在子组件中显式声明事件getModalBtn
,这告诉 Vue 这是一个自定义事件,父组件可以监听并触发它。$emit('getModalBtn', params)
:子组件触发getModalBtn
事件,并传递参数。- 父组件通过
@getModalBtn="getExchangeBtn"
来监听子组件的getModalBtn
事件。