是否可以从 Vue.js 2 中的组件访问事件侦听器

yav*_*vus 4 vue.js vuejs2

我在 Vue.js(2) 中有一个自定义组件:

Vue.component("modal-panel", {
    props: {
        id: {
            required: true
        },
        title: {} ,
        size: {
            validator: function(value) {
                return !value || value=="lg" || value=="sm";
            }
        }, 
        confirmLabel: {
            "default": "Yes",
        }, 
        closeLabel: {
            "default": "No"
        },
        confirm: {
            type: Function
        }
    },
    //...
    template: `
        //...
        <button type="button" class="btn btn-primary confirm" data-dismiss="modal" v-on:click="$emit('confirm')" v-if="confirm">{{confirmLabel}}</button>
        //...
    `
}
Run Code Online (Sandbox Code Playgroud)

这是使用组件的代码

<modal-panel title="New User" id="userModal" @confirm="doSomething">...</modal-panel>
Run Code Online (Sandbox Code Playgroud)

从组件代码可以看出,props中已经插入了confirm,并且模板中的按钮代码上有根据是否附加confirm监听器进行条件渲染。但是,按钮未呈现。我检查了组件dom和属性,但没有这样的信息。

是否可以根据 vue.js 中的组件是否附加特定侦听器来进行条件渲染?

谢谢。

Ber*_*ert 5

从 Vue 2.4 开始,Vue 组件有了一个$listeners属性。

包含父范围 v-on 事件侦听器(不带 .native 修饰符)。

此处记录了这一点。您可以通过检查属性来确定父级是否正在侦听特定事件$listeners


**原始答案**

对于组件来说,脱离自身来确定事物通常不是一个好的做法。

我建议您使用confirm回调属性。您可以将函数作为属性传递。然后您可以决定显示/隐藏是否收到回调的按钮。

Vue.component("modal",{
  props:["confirm"],
  template: `
    <div>
      <h1>Modal</h1>
      <button v-if="confirm" @click="confirm">Confirm</button>
    </div>
  `
})
Run Code Online (Sandbox Code Playgroud)

例子

编辑

可以确定组件上是否为给定事件定义了处理程序,但这需要检查内部 Vue 属性,并且您应该自行承担使用此属性的风险。

Vue.component("modal",{
  template: `
    <div>
      <h1>Modal</h1>
      <button v-if="hasConfirmHandler" @click="$emit('confirm')">Confirm</button>
    </div>
  `,
  computed:{
    hasConfirmHandler(){
      return !!this._events["confirm"]
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

_events如果处理程序是从父级定义的,则组件的属性将包含处理程序。

例子