1

given a child component Foo.vue

<template>
  ...
  <button @click="emit('bah', ...)">...</button>
  ...
</template>

<script setup>
const emit = defineEmits(['bah'])
...
</script>

is it possible to test within Foo.vue if the parent has actually defined @bah? e.g.

...
<div>
<Foo @bah="doSomething"/>
</div>
...

vue used to have a $listeners array and I assumed the process would be similar to the way one can test if the parent component has used slots with useSlots() but I'm struggling to find much beyond a conversation on a related subject here. Indeed: the docs here suggests that listeners have been merged into $attrs, but when I investigate useAttrs() onMounted I don't see any listeners.

<script setup>
import {onMounted, useAttrs} from 'vue'

const attrs = useAttrs()

onMounted(() => {
  console.log(attrs) // no attrs present
})
...

[edit] documentation suggests that defineEmits clears useAttrs (see earlier references). But does that mean you'd have to manually define event handlers instead to test if they're defined by the parent component?

1 Answer 1

1

Event listeners are translated to camel-cased on... props internally. They may not be available through regular props object, it's possible to access them on a vnode:

const rawProps = getCurrentInstance().vnode.props;

console.assert(rawProps.onBah);
1
  • 1
    (and in vue 2.7) console.assert(Object.keys(getCurrentInstance()?.$listeners || {}).includes('bah')) Commented Jul 9 at 15:45

Not the answer you're looking for? Browse other questions tagged or ask your own question.