无法在 Vue.JS 上捕获自定义事件

Posted

技术标签:

【中文标题】无法在 Vue.JS 上捕获自定义事件【英文标题】:Cannot catch custom events on Vue.JS 【发布时间】:2021-04-22 03:21:30 【问题描述】:

我正在尝试使用事件将数据从子组件传递到父组件,但我无法捕获它。该事件在子组件函数上触发,但不会在父组件函数上捕获。

有人能弄清楚为什么没有调用 callbackMethod 吗?

我已经尝试过使用 kebab-case 的其他名称,尝试不使用自定义数据/参数,尝试在模板标签上捕获事件,尝试将子组件包装到 div 中,尝试删除括号v-on 声明...


子组件:

html

              <v-btn
                  color="primary"
                  icon
                  small
                  elevation="1"
                  @click="openSettings"
              >
                <v-icon>
                  mdi-dots-vertical
                </v-icon>
              </v-btn>

javascript

export default 
  name: "ChildComponent",
  components: 
    OtherChild
  ,
  props: 
    my_prop: Object
  ,
  methods: 
    openSettings: function () 
      // always use kebab-case for event names!
      // (https://vuejs.org/v2/guide/components-custom-events.html)
      this.$emit("open-child-settings", this.my_prop)
      console.log("event")

    
  

父组件:

HTML

    <v-container>
      <ChildComponent @open-child-settings="callbackMethod($event)"/>
    </v-container>

JavaScript

export default 
    name: 'ParentComponent',
    components: 
      ChildComponent,
      OtherChildComponent
    ,
    methods: 
      callbackMethod: function (my_prop)
        this.settingsDialog  = true;
        this.tempProp = my_prop;
        console.log("callback")
      
    

依赖关系

  "dependencies": 
    "core-js": "^3.6.5",
    "dotenv": "^8.2.0",
    "vue": "^2.6.11",
    "vuetify": "^2.2.11"
  

编辑: 在沙盒上添加了代码,以便您可以看到整个全景图和 Vue.js 扩展的一些快照:

Project Sandbox, you can fork it and play with it! Event Propagation (Vue.js Extension) Components Tree (Vue.js Extension)

【问题讨论】:

【参考方案1】:

通过以下方式更新您的父组件:

<v-container>
      <ChildComponent @open-child-settings="callbackMethod"/>
</v-container>

根据我的理解,这里不需要 $event。所以,只需删除它并运行它。它会起作用的。

看到这个 - Share data from child to parent component

【讨论】:

@pinxau1000,我猜,你犯了一个玩具错误。否则,它会工作.. 我编辑了主要问题并添加了代码游乐场链接和一些打印屏幕。所有链接都在主要出版物的底部。【参考方案2】:

假设my_prop在子组件中定义,试试这个:

const childcomponent = Vue.component('child-component', 
  template: '#child-component',
  props: 
    my_prop: Object
  ,
  methods: 
    openSettings: function () 
      this.$emit("open-child-settings", this.my_prop); //pass my_prop
    
  
);

new Vue(
  el: '#app',
  vuetify: new Vuetify(),
  components:  childcomponent ,
  data: () => ( settingsDialog: false, tempProp: null, propData: id:1 ),
  methods: 
    callbackMethod: function (my_prop)
      this.settingsDialog  = true;
      this.tempProp = my_prop;
    
  
);
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script><link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">

<v-app id="app">
  <v-container>
    <childcomponent 
      @open-child-settings="callbackMethod($event)"
      :my_prop="propData"
    />
  </v-container>
  settingsDialog: settingsDialog<br>
  tempProp: tempProp
</v-app>

<template id="child-component">
  <v-btn
    color="primary"
    icon
    small
    elevation="1"
    @click="openSettings"
  >
    <v-icon>mdi-dots-vertical</v-icon>
  </v-btn>
</template>

【讨论】:

我的实现将子组件与父组件放在不同的 vue 文件中。我将 my_prop 更改为 this.my_prop 并将 my_prop 更改为一个数组,但仍然无法正常工作。在我的实现中,my_prop 是 Object 类型的子属性。道具: my_prop:对象 @pinxau1000 my_prop 的类型不是问题。关于文件组件,如果您在父级中导入子级并注册它,这应该不是问题。你可能遗漏了一个小细节。尝试将您的代码与上述解决方案进行比较,或者在小提琴中分享您的实现以获得进一步的支持。 我编辑了主要问题并添加了代码游乐场链接和一些打印屏幕。所有链接都在主要出版物的底部。 @pinxau1000 in Body.vue,你需要把@open-child-settings="callbackMethod($event)"放在&lt;Card/&gt;组件上而不是&lt;template&gt; 是的,它现在工作了!但是为什么在卡片组件上呢?在文档中声明应该在父组件上。

以上是关于无法在 Vue.JS 上捕获自定义事件的主要内容,如果未能解决你的问题,请参考以下文章

自定义事件在 Vue.js 组件中的应用

如何在子窗口小部件下使用 eventfilter 来捕获自定义事件

Vue.js 自定义事件问题

Vue组件及自定义事件

Vue.js 绑定到名称中带有点的 DOM 自定义事件(如引导事件)

有条件地在 vue js 中绑定自定义指令以“在元素事件之外单击”