I have the following Vue event handlers with contenteditable:
<div contentEditable="true"
v-on:keyup="changed($event, current, 0)"
v-on:paste="changed($event, current, 0)"
v-on:blur="changed($event, current, 0)"
v-on:delete="changed($event, current, 0)"
v-on:focused="changed($event, current, 0)"></div>
However, I have many places where I call the same code and the code is getting long and verbose. Is there a way to combine event handlers? Something like:
v-on:keyup:paste:blur:delete:focused
?
You can create your custom directive for this purpose. This sample may help you:
Vue.directive('wrap-on', {
bind: function(el, binding, vnode) {
// Keep function to remove the event later.
el.wrappedEventFunctions = el.wrappedEventFunctions || {};
el.wrappedEventFunctions[binding.rawName] = binding.value;
for (var key in binding.modifiers) {
// Check if element is a vue component
if (vnode.componentInstance) {
vnode.componentInstance.$on(key, binding.value);
} else {
el.addEventListener(key, binding.value);
}
}
},
unbind: function(el, binding, vnode) {
for (var key in binding.modifiers) {
if (vnode.componentInstance) {
vnode.componentInstance.$off(key, el.wrappedEventFunctions[binding.rawName]);
} else {
el.removeEventListener(key, el.wrappedEventFunctions[binding.rawName]);
}
}
}
})
This directive will add event handlers to the element. It checks if the element is a vue component; if it is a vue component it registers the events via $on
. If it is not a vue component it uses addEventListener
. You can change this behavior if you want.
And usage is like:
<input v-wrap-on.click.keydown="mixedCallback" />
Or:
<some-custom-component v-wrap-on.click.keydown="mixedCallback">
...
</some-custom-component>
I don't think that there is a way, currently, to combine event listeners like you're describing.
What you could do is make this div it's own wrapper component (named 'editable-wrapper', for example) and emit one change
event:
<div
contentEditable="true"
v-on:keyup="$emit('change', {$event, current} )"
v-on:paste="$emit('change', {$event, current} )"
v-on:blur="$emit('change', {$event, current} )"
v-on:delete="$emit('change', {$event, current} )"
v-on:focused="$emit('change', {$event, current} )">
</div>
And then you would only need to listen to one change event on the component (data
is an object with $event
, and current
properties):
<editable-wrapper @change="changed(data)"></editable-wrapper>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With