2

Here is the situation, I use v-for to display lots of data in JSON as seperate buttons. What I want to do is when i click single one of those buttons, the button's background color will change. I want to use @click to bind function to each button, and in that function, do as this

theButtonDOM.style.backgroundColor = 'black';

So, how can I get that DOM whose div element is generated by v-for? OR any other solution to solve this 'background color change' problem?

yuan
  • 1,701
  • 2
  • 13
  • 24

4 Answers4

1

You can pass $event

<button @click="changeColor($event)"></button>

Then in your method

this.changeColor = function(evt){ evt.target.style.backgroundColor = 'red'; }
Abana Clara
  • 4,602
  • 3
  • 18
  • 31
1

You can use @click and v-bind:class. When you click on an item, its index will be stored in selectedItem. Then v-bind:class automatically will add the class to the item that has an index equal to selectedItem.

new Vue({
  el: '#app',
  data: {
    selectedItem: ""
  },
  computed:{},
  methods: {}
  }
)
.selectedItemClass {
  background-color:green
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">

  <div v-for="(item,index) in ['aa','bb','cc']"
    v-bind:class="{  selectedItemClass : (selectedItem === index) }"
    @click="selectedItem = index"
  >{{item}}</div>
  
</div>
eag845
  • 1,013
  • 1
  • 11
  • 16
1

Any time you trigger a click event in Vue template, you can access the event adding the special variable $event as argument to the function.

<button @click="my_method($event, other_argument)"></button>

and then access the target of the event inside the method:

methods: {
    my_method(event, other_paramethers) {
        let button = event.target
}
}

Even just with bind the method to the @click event without any argument, you can access the event as your first argument.

<button @click="my_method"></button>
...
methods: {
    my_method($event) {
        let button = $event.target
}
}

Then you can play with your button.

Look at this stackoverflow question and the Vue documentation for more details.

tony19
  • 125,647
  • 18
  • 229
  • 307
JoseVL92
  • 431
  • 4
  • 4
1

I am assuming you want the buttons to act as individual switches and not a radio group, as implemented in the answer by @eag845.


You could add a 'clicked' boolean attribute to your JSON Objects.

arrayOfJSONObjects.forEach(object => object.clicked = false); // Add 'clicked' attribute and init to false

Then use that attribute as a conditional to bind a CSS class using v-bind:class or :class, and then toggle the attribute within @click or whatever event handler function you put inside @click.

<button
    v-for="btn in arrayOfJSONObjects"
    :class="{ 'button--activated': btn.clicked }"
    @click="btn.clicked = !btn.clicked"
>{{btn.foo}}</button>

Stylez

.button {
  background-color: white;
}
.button--activated {
  background-color: black;
}