I want to execute a function when I'm clicking on elements in the dom with a specific class. It just doesn't work, but I'm also receiving any error. This is my
code snippet:
methods: {
initTab: function(){
document.querySelectorAll('.element').onclick = this.nextTab()
}
},
mounted: function () {
this.initTab()
}
I I want to execute the function every time I click on the element. Would be very thankful if anybody could help me :)
I want to execute a function when I'm clicking on elements in the dom with a specific class. It just doesn't work, but I'm also receiving any error. This is my
code snippet:
methods: {
initTab: function(){
document.querySelectorAll('.element').onclick = this.nextTab()
}
},
mounted: function () {
this.initTab()
}
I I want to execute the function every time I click on the element. Would be very thankful if anybody could help me :)
Share Improve this question edited Jun 10, 2020 at 9:13 Boussadjra Brahim 1 asked Sep 13, 2018 at 14:25 luki512luki512 2371 gold badge6 silver badges18 bronze badges 2- are you working with single file ponents? i have a solution to your specific need and i want to know how you are implementing vue – Boussadjra Brahim Commented Sep 13, 2018 at 19:09
- Hello, I‘m just using vue as a script without ponents. I just have a few instances :) But I‘m thinking about switching to single file ponents – luki512 Commented Sep 13, 2018 at 19:12
3 Answers
Reset to default 4There's very little need (if at all) for document.querySelectorAll()
in a Vue app.
In this situation you can take advantage of delegation:
<div @click="onClick">
<!-- Clicks on any element inside this div will be handled -->
</div>
methods: {
onClick(e) {
if (e.target.classList.contains('element')) {
// Handle the click
}
}
}
Add @click="initTab($event)"
to the document or template root, that allows you to track every click
event on your template, that way you could put your logic to the elements which have only .element
class name. If you're using it in a ponent you could do : <template> <div @click="initTab($event)"> ... </div> </template>
var app = new Vue({
el: '#app',
data() {
return {
}
},
methods: {
nextTab(){
console.log("You clicked on an element with class name =element")
},
initTab(event){
let targetClassNames=event.target.className.split(" ");
targetClassNames.filter(e=>{
if(e==="element"){
this.nextTab();
}
});
}
},
mounted() {
}
})
#app{
height:100px;
display:grid
}
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/vue.js"></script>
<div id="app" @click="initTab($event)">
<button class="element">1</button>
<button class="element btn">2</button>
<button class="btn">3</button>
<button class="element btn-primary">4</button>
<button class="btn elementory">5</button>
</div>
You're trying to use general javascript logic within vue. This is not often a good idea.
What I do in such cases is something like this:
<ponent-name @click="nextTab(tabName)"></ponent-name>
However, in a v-for loop you can also do something like this:
<ul v-for="tab in tabs">
<li @click="nextTab(tab)">{{tab}}</li>
</ul>
That way in methods you only need:
methods: {
nextTab: function(tab){
// whatever it is you want to do here
}
},
And you won't need mounted at all.
Conclusion: try to avoid repetition by creating ponents or elements (like li) that repeat - not by trying to add an event-listener to a class.