Using Vue 2.1.10
I can bind to DOM events with v-on
directive. For example:
v-on:click
To bind to DOM click. But I can't figure how to bind to an event that has dots in the name. such as "show.bs.modal" from bootstrap.
Currently, I use a workaround binding in the created
hook with Regular DOM Methods, but I really would like to use the declarative syntax for that. How can this be achieved? thanks
EDIT: The question is about allowed syntax: how can I do something like:
Vue.component('comp',{
template:'<div v-on:show.bs.modal="sunrise"></div',
methods:{
sunrise:function(e){
}
}
})
I was facing the very same problem when working on old projects.
Luckily I found the answer here: vue2 doc
<!-- object syntax (2.4.0+) -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
This works on Bootstrap 5.1.1 with Vue 2.16.14:
<div class="modal" v-on="{ 'hide.bs.modal': handleModalClose }">
...
</div>
I think dots are not supported in v-on
but you could create a custom directive to create an event listener for that event.
Not sure if there is something easier but something like in the demo below or this fiddle should work.
The demo creates a new event with dots in name but that should also work with bootstrap events (not tested). Please let me know if it's not working with bootstrap and I'll have a look.
Unbinding only works if you're using v-if
. If you're removing that element with Javascript directly. The event will still be there.
var helloEvent = new Event('demo.event.hello');
document.addEventListener('demo.event.hello', function(e) {
// this is just for testing event dispatching!
console.log('main event listener');
}, false);
const bindCustomEvent = {
getName: function(binding) {
return binding.arg + '.' +
Object.keys(binding.modifiers).map(key => key).join('.');
},
bind: function(el, binding, vnode) {
const eventName = bindCustomEvent.getName(binding);
console.log(el, eventName);
document.addEventListener(eventName, binding.value);
},
unbind: function(el, binding) {
const eventName = bindCustomEvent.getName(binding);
console.log('unbinding', eventName);
document.removeEventListener(eventName, binding.value);
}
};
Vue.directive('bindCustomEvent', bindCustomEvent);
new Vue({
el: '#app',
data() {
return {
enabled: true,
eventMsg: ''
};
},
methods: {
sunrise: function(e) {
console.log('received event');
this.eventMsg = 'received event';
},
testEvent: function() {
document.dispatchEvent(helloEvent);
},
toggle: function() {
console.log('toggle', this.enabled);
this.enabled = !this.enabled;
if (!this.enabled) {
this.eventMsg = '';
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<div id="app">
<div v-bind-custom-event:demo.event.hello="sunrise" v-if="enabled">
Hello, {{eventMsg}}
</div>
<!--
The following markup is not working
<div v-on="demo.event.hello:sunrise" v-if="enabled">
Hello, {{eventMsg}}
</div>-->
<button @click="testEvent()">
Change
</button>
<button @click="toggle">
<span v-if="enabled">disable custom event</span>
<span v-else>enable custom event</span>
</button>
</div>
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