2

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 :)

2
  • are you working with single file components? i have a solution to your specific need and i want to know how you are implementing vue Commented Sep 13, 2018 at 19:09
  • Hello, I‘m just using vue as a script without components. I just have a few instances :) But I‘m thinking about switching to single file components Commented Sep 13, 2018 at 19:12

3 Answers 3

4

There'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
    }
  }
}
Sign up to request clarification or add additional context in comments.

Comments

2

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 component 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.net/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>

Comments

0

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:

<component-name @click="nextTab(tabName)"></component-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 components or elements (like li) that repeat - not by trying to add an event-listener to a class.

2 Comments

Thanks a lot for your answer. I wanted to automate every class, because I've got many elements of that on my page and won't to add the @click event every time manually.
Now you have to add that class many times. Is that really less work?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.