Home > database >  Vue3 - pass multiple event listeners along with their handlers to child component
Vue3 - pass multiple event listeners along with their handlers to child component

Time:09-23

in Vue3 I can do the following:

Parent Component:

<ChildComponent :props="{ id: 'the-id', class: 'the-class' }" />

ChildComponent:

<template>
    <input v-bind="props" />
</template>

<script>
export default {
    props: {
        props: { type: Object }
    }
}
</script>

This will result in HTML like this:

<input id="the-id" class="the-class" />

I'm still learning Vue and I was wondering if I could do the same thing with event listeners / handlers.

With reusable components I might need different event listeners / handlers, depending on where I use the component. In one form I might need only an @input="..." in the child component, in another form I might also need an @blur="..." or I might not need an event listener at all.

Is it possible to do something similar to this?

ParentComponent:

<ChildComponent :events="{ input: function() { alert('input!'); }, blur: function() { alert('blur!'); } } />

ChildComponent:

<template>
    <input @events />
</template>

<script>
export default {
    props: {
        props: { type: Object }
    }
}
</script>

Thank you ;)

CodePudding user response:

My recommendation would be to define the different events though Vue's Custom Events; The custom events would allow the users of the component to choose which event to subscribe to and handle it accordingly.

https://vuejs.org/v2/guide/components-custom-events.html

CodePudding user response:

The root element of a component automatically inherits all non-prop attributes (including event listeners) applied to the component from the parent. So if <input> were really at the root in ChildComponent, you wouldn't need to declare anything, and you could simply apply attributes to ChildComponent as if it were the input itself:

<ChildComponent id="the-id" class="the-class" @blur="onBlur" />

demo 1

However, this will break as soon as you add another element to ChildComponent because <input> would no longer be the root. It also would be a problem if you wanted to switch the root element (e.g., a <label> that wraps the <input>).

To disable automatic attribute inheritance, allowing control of where to apply the inherited attributes, set inheritAttrs: false in component options. (This doesn't need to be disabled when there are multiple root nodes, as it only applies for single-root components.) Then manually v-bind the $attrs prop to any element within:

<template>
  <label>My input: <input v-bind="$attrs"></label>
</template>

<script>
export default {
  inheritAttrs: false,
}
</script>

demo 2

  • Related