vue.js 检查组件是否附加了事件侦听器

bbuxkriu  于 2023-05-18  发布在  Vue.js
关注(0)|答案(6)|浏览(195)

假设有<Form>组件。它可以通过附加一个@cancel事件侦听器调用,如果是这样的话,我想显示触发该事件的取消按钮。如果没有@cancel事件,取消按钮应不可见。
是否有一种方法可以检查组件是否附加了事件侦听器?
目前我做:

<template>
  <form>
    <button v-if="cancelEventPassed" @click="$emit('cancel')">Cancel</button>
  </form>
</template>

然后这样称呼它:

<Form :cancelEventPassed="true" @cancel="handle_cancel" />

要么

<Form/>

是否可以不使用任何额外的属性,如cancelEventPassed

nhn9ugyo

nhn9ugyo1#

当有侦听器附加到组件时,它们在组件的$listeners属性中可用。
可以使用该属性确定特定侦听器是否可用。例如,这里有一个计算属性,用于检查cancel侦听器是否存在。

computed:{
  hasCancelListener(){
    return this.$listeners && this.$listeners.cancel
  }
}

下面是一个组件中使用的例子。

console.clear()

Vue.component("CustomForm", {
  template:`
    <div>
      <h1>Custom Form</h1>
      <button v-if="hasCancelListener" @click="$emit('cancel')">I have a listener!</button>
    </div>
  `,
  computed:{
    hasCancelListener(){
      return this.$listeners && this.$listeners.cancel
    }
  },
})

new Vue({
  el: "#app",
  methods:{
    onCancel(){
      alert('canceled')
    }
  }
})
<script src="https://unpkg.com/vue@2.4.2"></script>
<div id="app">
  <custom-form @cancel="onCancel"></custom-form>
  <hr>
  <custom-form></custom-form>
</div>
jmo0nnb3

jmo0nnb32#

在Vue 3中,$listeners对象被删除了。侦听器现在是$attrs对象的一部分,前缀为on
为了检查子组件中是否存在特定侦听器,您可以执行以下操作:

computed: {
  hasCancelListener() : boolean {
    return (this.$attrs && this.$attrs.onCancel) as boolean
  }
}

子组件称为:

<custom-form @cancel="onCancel"></custom-form>
34gzjxbg

34gzjxbg3#

Vue3示例

this.$attrs.onCancel

说明

Vue 3删除了$listeners对象,而不是监听器将与$attrs对象分开,前缀为on..

参考

https://v3-migration.vuejs.org/breaking-changes/listeners-removed.html#overview

ibps3vxo

ibps3vxo4#

因为@prerak-sola的解决方案不起作用,如果你这样定义发射(如Adam Reis所示):

const emit = defineEmits<{
  (e: 'click', v: MouseEvent): void;
  (e: 'update:modelValue', v: MouseEvent): void;
}>();

我发现,由于vue将所有props转换为一个对象,并在每个event-name前添加前缀on,所以你只需检查vnode中是否定义了属性(事件监听器):

const hasClickEventListener = computed(() => !!getCurrentInstance()?.vnode.props?.onClick);
const hasModelValueUpdateListener = computed(() => !!getCurrentInstance()?.vnode.props?.['onUpdate:modelValue']);

然而,我在官方文档中找不到任何关于这一点的信息(这比使用useAttrs要困难得多)。所以要谨慎使用。

csbfibhn

csbfibhn5#

你可以像这样检查监听器是否存在:this._events['listener-name']

krcsximq

krcsximq6#

如果您正在寻找Vue 3 script setupsetup function解决方案,您可以在getCurrentInstance函数中检查attrs

<template>
  <form>
    <button @click="$emit('cancel')">Cancel</button>
  </form>
</template>
<custom-form @cancel="onCancel"></custom-form>
onMounted(() => {
  const instance = getCurrentInstance() // only available inside lifecycle hooks
  console.log(instance?.attrs?.onCancel)
})

相关问题