I need to capture all click events triggered by the user inside my Vue.js application. My first step was to add an onclick listener to the #app
div:
<div id="app" @click="onClickApp"></div>
// ...
<script>
export default {
methods: {
onClickApp() {
// increment counter in vuex store
}
}
</script>
This captures all click events happening directly inside the App component. The issue is that I'm using a Bootstrap Modal (provided via BootstrapVue) and I need to capture the clicks inside it as well. This is not working at the moment, even if I set another @click listener on the <b-modal></b-modal>
component (syntax for vue-cli).
This is what I also tried (in main.js
):
new Vue({
router,
store,
render: h => h(App),
mounted: function() {
this.$el.addEventListener('click', this.onClickVue)
},
beforeDestroy: function () {
this.$el.removeEventListener('click', this.onClickVue)
},
methods: {
onClickVue: function (e) {
this.$store.commit(mutationTypes.INCREMENT_CLICKS)
}
});
Same problem, clicks inside the Bootstrap Modals are not firing a click event.
I could only get this to work by using the mouseup
event..
CodePen mirror: https://codepen.io/oze4/pen/PgKWRW?editors=1010
new Vue({ el: "#app", data: { modalShow: false }, mounted() { document.addEventListener("mouseup", e => { let m = `x: ${e.clientX} | y: ${e.clientY}`; console.log(m); }) } });
<script src="https://unpkg.com/vue@2.5.17/dist/vue.min.js"></script> <script src="https://unpkg.com/bootstrap-vue@2.0.0-rc.11/dist/bootstrap-vue.min.js"></script> <link href="https://unpkg.com/bootstrap@4.1.3/dist/css/bootstrap.min.css" rel="stylesheet" /> <link href="https://unpkg.com/bootstrap-vue@2.0.0-rc.11/dist/bootstrap-vue.css" rel="stylesheet" /> <div id="app"> <div style="margin: 5px 0px 0px 40px"> <b-button @click="modalShow = !modalShow">Open Modal</b-button> <b-modal v-model="modalShow">Hello From Modal!</b-modal> </div> </div>
A better answer is just adding ev to onClickApp, so do onClickApp(ev) inside your methods.
Now, you have access to the click event.
This should work ;-)
- <div id="app" @click="onClickApp"></div>
+ <div id="app"></div>
// ...
<script>
export default {
methods: {
onClickApp() {
// increment counter in vuex store
}
},
+ mounted() {
+ window.document.addEventListener('click'), this.onClickApp)
+ },
+ beforeDestroy() {
+ window.document.removeEventListener('click'), this.onClickApp)
+ }
</script>
I couldn't find a way to test with Bootstrap Vue, but this might do.
TLDR: Create a plugin which will run whenever any of your components are instantiated. Put a listener on the root element.
https://codesandbox.io/s/kxwz85pl65
const MyPlugin = {
install(Vue, options) {
Vue.mixin({
mounted() {
setTimeout(() => {
let cb = this.$root.$el.onclick;
this.$root.$el.onclick = (e) => {
alert("element clicked");
if (cb) {
cb(e);
}
};
}, 10);
}
});
}
};
EDIT:
As of writing this Vue Bootstrap
doesn't seem to allow click events for the modal itself, though elements inside of it can be clicked.
https://codesandbox.io/embed/kxwz85pl65
EDIT again, you can use set timeout if you really want to. It's a bit of a hack though.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.