检查组件是否附加了事件监听器

问题描述 投票:0回答:8

假设有一些

<Form>
组件。可以使用附加的
@cancel
事件侦听器来调用它,如果是这种情况,我想显示触发此事件的取消按钮。如果没有
@cancel
事件,取消按钮应该不可见。

有没有办法检查组件是否附加了事件侦听器?

目前我做的是:

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

并这样称呼它:

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

都可以

<Form/>

是否可以在不使用任何其他属性(如

cancelEventPassed
)的情况下实现这一目标?

javascript vue.js vuejs2 vue-component
8个回答
62
投票

当组件附加了侦听器时,它们可以在组件的

$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/[email protected]"></script>
<div id="app">
  <custom-form @cancel="onCancel"></custom-form>
  <hr>
  <custom-form></custom-form>
</div>


14
投票

在 Vue 3 中,

$listeners
对象已被删除。侦听器现在是
$attrs
对象的一部分,并且 带有
on
前缀。

为了检查子组件中是否存在特定侦听器,您可以执行以下操作:

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

子组件称为:

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

6
投票

因为 @prerak-sola 的解决方案不起作用,如果您像这样定义发射(如 所示) 亚当·里斯):

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

我发现,由于 vue 将所有 props 转换为对象,并且只是在每个事件名称之前添加前缀

on
,因此您只需检查该属性(事件侦听器)是否在
vnode
中定义:

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

但是,我在官方文档中找不到任何有关此内容的信息(并且它比使用

useAttrs
困难得多)。所以请谨慎使用。


2
投票

此示例适用于 Vue 3

this.$attrs.onCancel

说明

Vue 3 删除了

$listeners
对象,而是侦听器将与带有
$attrs
前缀的
on..
对象分开。

参考

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


0
投票

您可以这样检查监听器是否存在:

this._events['listener-name']


0
投票

如果您在这里寻找 Vue 3

script setup
setup function
解决方案,您可以检查
attrs
函数中的
getCurrentInstance

<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)
})

0
投票

Vue 2.7 脚本设置示例

import {useListeners, computed} from 'vue';

const listeners = useListeners();
const hasCancelListener= computed(() => {
    return typeof listeners['cancel'] !== 'undefined';
});

0
投票

在 Vue 3 中

const thisInstance = getCurrentInstance();

const hasTaskClickedListener = computed(() => {
  if (!thisInstance) return null;

  return thisInstance.attrs?.onClicked;
});

说明:

  • this
    与 vue 3 中的
    getCurrentInstance()
    相同
  • listeners 对象通过前缀为“on”的属性进行更改,如
    onClick
    onDelete
  • getCurrentInstance()
    始终放在设置脚本上,除非你总是为 null(vue 无法看到其实例时的值)
© www.soinside.com 2019 - 2024. All rights reserved.