使用动态组件和自定义事件时的 VueJS 警告
Posted
技术标签:
【中文标题】使用动态组件和自定义事件时的 VueJS 警告【英文标题】:VueJS warning when using dynamic components and custom-events 【发布时间】:2021-04-09 18:57:23 【问题描述】:所以,我收到了这个警告:
" 无关的非发射事件侦听器 (addNewResource) 已传递给组件,但无法自动继承,因为组件呈现片段或文本根节点。如果侦听器仅用作组件自定义事件侦听器,请使用“发射”选项。”
我不明白为什么。我正在使用带有 2 个自定义事件的动态组件。我尝试将两个发出的事件都添加到两个组件的 emits
对象中。
App.vue
<template>
<AppHeader />
<NavigationBar @select-component="selectComponent" />
<keep-alive>
<component
:is="selectedComponent"
v-bind="componentProps"
@delete-resource="deleteResource"
@add-new-resource="addNewResource"
></component>
</keep-alive>
</template>
<script>
import AppHeader from "./components/SingleFile/AppHeader.vue";
import NavigationBar from "./components/NavigationBar.vue";
import LearningResources from "./components/LearningResources.vue";
import AddResource from "./components/AddResource.vue";
export default
components:
AppHeader,
NavigationBar,
LearningResources,
AddResource,
,
data()
return
selectedComponent: "learning-resources",
learningResources: [
name: "Official Guide",
description: "The official Vue.js documentation",
link: "https://v3.vuejs.org",
,
name: "Google",
description: "Learn to google...",
link: "https://www.google.com/",
,
],
;
,
methods:
selectComponent(component)
this.selectedComponent = component;
,
deleteResource(name)
this.learningResources = this.learningResources.filter(
(resource) => resource.name !== name
);
,
addNewResource(newResourceObject)
const newResource =
name: newResourceObject.title,
description: newResourceObject.description,
link: newResourceObject.link,
;
this.learningResources.push(newResource);
,
,
computed:
componentProps()
if (this.selectedComponent === "learning-resources")
return
learningResources: this.learningResources,
;
return null;
,
,
;
</script>
AddResource.vue
<template>
<base-card>
<template #default>
<form @submit.prevent>
<div>
<label for="title">Title</label>
<input type="text" v-model="newResource.title" />
</div>
<br />
<div>
<label for="description">Description</label>
<textarea rows="3" v-model="newResource.description" />
</div>
<br />
<div>
<label for="link">Link</label>
<input type="text" v-model="newResource.link" />
</div>
<button @click="$emit('add-new-resource', newResource)">
Add Resource
</button>
</form>
</template>
</base-card>
</template>
<script>
import BaseCard from "./Base/BaseCard.vue";
export default
components:
BaseCard,
,
emits: ["add-new-resource"],
data()
return
newResource:
title: "",
description: "",
link: "",
,
;
,
;
</script>
LearningResources.vue
<template>
<base-card v-for="resource in learningResources" :key="resource.name">
<template #header>
<h3> resource.name </h3>
<button @click="$emit('delete-resource', resource.name)">Delete</button>
</template>
<template #default>
<p> resource.description </p>
<p><a :href="resource.link">View Resource</a></p>
</template>
</base-card>
</template>
<script>
import BaseCard from "./Base/BaseCard.vue";
export default
components:
BaseCard,
,
props:
learningResources: Array,
,
emits: ["deleteResource"],
;
</script>
【问题讨论】:
【参考方案1】:似乎是因为<component>
被用于两个独立的组件,它们都不会发出与另一个相同的事件。
你可以试试disabling each components' attribute inheritance:
export default
...
inheritAttrs: false
...
如果这不符合您的需要,您可以重构逻辑以处理两个发出的事件,即将事件重命名为共享名称,如"addOrDeleteResource"
,然后确定在App.vue
中发出的事件并处理它相应地。
【讨论】:
传递的props和emits事件没有传递给$attrs,所以我不能使用第一个建议 第一个建议不起作用怎么办?我测试了它,它对我有用。 如果您从我的回答中添加 sn-p:inheritAttrs: false
在export default ...
中的任何位置,它应该可以工作
现在可以了。谢谢。但是现在我有另一个问题,它是如何以及为什么起作用的? =))
正如错误所说:事件...could not be automatically inherited
。因此,通过禁用属性继承,您可以防止编译器运行此步骤并尝试设置组件不需要的自定义事件。不过,我不确定这会如何影响您的其他属性,所以请留意,如果您遇到任何错误,请尝试使用$attrs
,就像文档说的那样以上是关于使用动态组件和自定义事件时的 VueJS 警告的主要内容,如果未能解决你的问题,请参考以下文章