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" />
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>