vue 3 发出警告“ Extraneous non-emits event listeners”

回答 4 浏览 4.7万 2020-10-06

我试图使用组合API将数据从子项发送到父项。

我得到了以下的警告。

[Vue warn]: Extraneous non-emits event listeners (updatedcount) 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.at <HelloWorld onUpdatedcount=fn > at

childcomponent.vue


<template>
  <h1>{{ store.count }}</h1>
  <button @click="fired">click me</button>
</template>

<script>
import useStore from "../store/store.js";
export default {
  name: "HelloWorld",
  setup(_,{ emit }) {
    const store = useStore();

    const fired = () => {
      store.count++;
      emit("updatedcount", store.count);
    };

    return {
      store,
      fired
    };
  },
};
</script>


parentcomponent.vue


<template>
  <div>
    {{ hello }}
    <br />
    <br />
    <input type="text" v-model="hello.searchQuery" />
    <br><br>
    <button @click="hello.count--">click me too!</button>
    <hello-world @updatedcount="mydata" />
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";
import useStore from "./store/store.js";

export default {
  components: {
    HelloWorld,
  },
  setup() {
    const hello = useStore();

    function mydata(event) {
      console.log(event);
    }

    return {
      hello,
      mydata
    };
  },
};
</script>

Fanna1119 提问于2020-10-06
所接受的答案非常有效,但你也可以把你的子组件包在一个单一的div中。Coz 2022-10-16
4 个回答
#1楼 已采纳
得票数 91

我认为你需要在你的组件中定义emitshttps://v3.vuejs.org/guide/component-custom-events.html#defining-custom-events

export default {
  name: "HelloWorld",
  emits: ["updatedcount"], // <--- add this line
  setup(_,{ emit }) {
    ...
  },
};
Thomas 提问于2020-10-06
Kos 修改于2021-07-01
@Fanna1119 我也是花了一段时间才再次找到它,所以不要责怪自己;)Thomas 2020-10-06
请注意,现在最好是按照你的方式来命名事件--没有连字符,只是所有小写字母。如果你把它命名为kebab-case,运行时就会抱怨你没有用camelCase声明它是一个emit;另一方面,如果你把它命名为camelCase,EsLint会抱怨,因为事件应该是kebab-case。Tobias Feil 2020-11-20
谢谢你,宇宙的创造者,创造了SoF,让善良的人们可以发布如此好的答案。Michael Zelensky 2021-08-03
它对我来说是有效的,谢谢SefaUn 2022-01-13
@MichaelZelensky 我想你的意思是感谢你Jeff Atwood和Joel Spolsky 😏。hitautodestruct 2022-01-20
#2楼
得票数 7

更新的内容。

在vue 3的脚本设置中,你要做的是

const emits = defineEmits(["updatedcount"])

emits("updatedcount", store.count);
Fanna1119 提问于2022-02-24
#3楼
得票数 0

当我在自己的vue 3应用程序中看到这个错误时,我发现将一个组件的模板内容包裹在一个空的div中可以解决我的问题,我相信这与错误信息中的" could not be automatically inherited"部分有关。

似乎vue的工作方式是,vue会尝试使用属性继承来处理@click和@input这样的普通事件,以传递给底层元素,但当一个组件的根部有多个兄弟姐妹元素时,它不知道该选择哪一个。

请注意,这些事件可能会改变一些行为,因为新的包装父 div 现在会有直接与之相连的事件。

<template>
  <div>
    <h1>{{ store.count }}</h1>
    <button @click="fired">click me</button>
  </div>
</template>
Matt 提问于2022-11-17
#4楼
得票数 -1

在vue3中,你必须定义emits,你的子组件看起来像这样。

childcomponent.vue:

    <template>
      <h1>{{ store.count }}</h1>
      <button @click="fired">click me</button>
    </template>
    
    <script>
    import useStore from "../store/store.js";
    export default {
      name: "HelloWorld",
      emits :{
          updatedcount: null,
        },
      data: () => ({
            store: useStore(),
      }),
      methods:
        fire () {
          store.count++;
          this.$emit("updatedcount", store.count);
        },
      
    };
    </script>
Pep Marxuach 提问于2022-09-15
您的答案可以通过其他支持信息得到改进。请编辑以添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到更多关于如何写出好的答案的信息。Community 2022-09-20