I'm creating a button component in VueJS. I've made a dynamic event with a prop, plus event function and params as props as well. That works fine, the parent can set whatever event to trigger a method. However I want to be able to set modifiers on that event as well but don't see a way to do that. Is it possible?
The button component:
<button : role="button"
@[event]="onEvent(eventParams)"
:disabled="disabled">
<slot></slot>
</button>
The parent:
<Button
:event="'click'"
:onEvent="logEvent"
:eventParams="'This is a test message'">Test button</Button>
Adding a static modifier to the dynamic event works @[event].prevent=...
but I want to be able to set the modifier from a prop, or not have it at all.
I also tried setting up an event listeners object but can't see a way to add modifiers to those either. At least in this option I can pass the event and preventdefault the old fashioned way, like our grandparents did.
moveAllListeners() {
const me = this
return Object.assign({},
this.$listeners,
{
click(e) {
e.preventDefault()
me.moveAll()
},
mouseenter(e) {
console.log('Mouse entered');
}
}
)
}
CodePudding user response:
Event modifiers cannot be dynamic because they are applied at "compile time" (when the template is compiled).
You'll have to implement this all manually; how you do it exactly is up to you, but it could be something like this:
<button @[event]="onEvent">
props: [
'event',
'eventParams',
'eventPrevent',
],
methods: {
onEvent(e) {
if (this.eventPrevent) {
e.preventDefault()
}
// Use this.eventParams here...
}
}
I'm not sure what your requirements are, but it seems like this is a bad approach from the start. Why does a custom Button component need this kind of behavior? Why do you need Button to operate like this?
CodePudding user response:
I am not quite sure why you would need to operate such magic. Can you provide a bit more informations about your requirements please ?
Why can't you just do like this :
<button
:
role="button"
:disabled="disabled"
v-on="$listeners"
>
<slot></slot>
</button>
<Button @click="logEvent('This is a test message')">
Test button
</Button>
The only reason I can imagine that would require to have these in a prop, would be because of some dynamic actions set up.
But you could have something like this in your parent component:
<template>
<Button
v-for="(button, i) in dynamicButtons"
:key="`button_${i}`"
@[button.event]="button.action"
>
Test button
</Button>
</template>
<script>
export default {
name: 'Sandbox',
data () {
dynamicButtons: [
{
content: 'Test button 1',
event: 'click',
action: () => logEvent('Click w/o prevention')
},
{
content: 'Test button 2',
event: 'click',
action: (e) => {
e.preventDefault()
logEvent('Click with prevention')
}
},
{
content: 'Test button 3'
event: 'mouseenter',
action: logEvent('Mouse entered')
}
]
},
/* ... */
}
</script>