首页 > 解决方案 > 使用动态组件和自定义事件时的 VueJS 警告

问题描述

所以,我收到这个警告:

" 无关的非发射事件侦听器 (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>

标签: javascriptvue.jsvue-componentvuejs3

解决方案


似乎是因为<component>被用于两个独立的组件,它们都不会发出与另一个相同的事件。

您可以尝试的一件事是禁用每个组件的属性继承

export default {
    ...
    inheritAttrs: false
    ...
}

如果这不符合您的需要,您可以重构逻辑以处理两个发出的事件,即将事件重命名为共享名称,如"addOrDeleteResource",然后确定正在发出的事件App.vue并相应地处理它。


推荐阅读