radeveloper
radeveloper

Reputation: 946

How to change a specific (this) button class when click on. Using Vue.js 2.0

When clicked the any of the buttons they are all turns active. So what i want is just the clicked one should be changed.

var vm = new Vue({
	el: '#toolBtns',
	data: {
		isActive: false
	},
	computed: {
		activeClass: function () {
			return {
				active: this.isActive
			};
		}
	}
});
<div class="btn-group" role="group" id="toolBtns">
  <button class="btn" type="button" @click="isActive = !isActive" :class="activeClass">Btn1</button>
  <button class="btn" type="button" @click="isActive = !isActive" :class="activeClass">Btn2</button>
  <button class="btn" type="button" @click="isActive = !isActive" :class="activeClass">Btn3</button></div>

Upvotes: 5

Views: 21981

Answers (3)

Xie Jun
Xie Jun

Reputation: 59

You don't need to set 'isActive: false', and you don't need to bind isActive to each of the items. you can do as follows: 1, declare an array, called 'candidates', then each item clicked will be pushed into candidates. 2, declare a function, called 'contains()' which checks if an item is in the candidates array. 3, bind contains() to each item. 4, in CSS, give 'clicked' some style.

html code:

<body>
    <div id="toolBtns">
        <button v-for="item in buttons" v-on:click="provide(item)" v-bind:class="{clicked: contains(candidates, item)}" type="button">{{ item.name }}
        </button>
    </div>
</body>

javascript code:

var toolBtns = new Vue({
el: '#toolBtns',
data: 
{
    buttons: [
        {name: 'Btn1'},
        {name: 'Btn2'},
        {name: 'Btn3'},
    ],
    candidates: [],
},
methods:
{
    provide: function(item)
    {
        if(this.candidates.indexOf(item) == -1)
        {
            this.candidates.push(item);
        }
        else
        {
             this.candidates.splice(this.candidates.indexOf(item), 1);
        }
    },
    contains: function(arr, item)
    {
        return arr.indexOf(item) != -1;
    },
}
});

CSS code

.clicked{
    background-color: red;
}

here is the jsfiddle example https://jsfiddle.net/JoyAndBrave/anzdzq4L/6/

Upvotes: 3

Saurabh
Saurabh

Reputation: 73619

You probably need a variable to find which button is currently selected. And you can use that variable to dynamically bind correct class: with : :class="{active: activeBtn === 'btn1' }".

Benefit of this approach is you have only one variable instead of array to save which button is currently selected, so you dont have to iterate on the array everytime you select a button.

var vm = new Vue({
	 el: '#toolBtns',
	 data: {
 		activeBtn:''
	 }
 });
.active{
  background-color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<div id="toolBtns">
<div class="btn-group" role="group" id="toolBtns">
  <button class="btn" type="button" @click="activeBtn = 'btn1'" :class="{active: activeBtn === 'btn1' }">Btn1</button>
  <button class="btn" type="button" @click="activeBtn = 'btn2'" :class="{active: activeBtn === 'btn2' }">Btn2</button>
  <button class="btn" type="button" @click="activeBtn = 'btn3'" :class="{active: activeBtn === 'btn3' }">Btn3</button></div>
</div>

See working fiddle here.

Upvotes: 14

Cristi Jora
Cristi Jora

Reputation: 1752

The direction of the solution above is correct but it's very vulnerable to errors since it uses indexes directly. As suggested in the answer above, doing a v-for would basically solve your problem.

var vm = new Vue({
 el: '#toolBtns',
 data: {
    buttons:[{name:'Btn1',active:false},{name:'Btn2',active:false},
            {name:'Btn3',active:false}]
 },
 methods: {
   toggleActiveClass:function(index){
     this.buttons[index].active=!this.buttons[index].active;
   }
  }
});


 <div class="btn-group" role="group" id="toolBtns">
   <button v-for="(btn, index) in buttons" type="button" 
               @click="toggleActiveClass(index)"
              :class="{active: btn.active}">{{btn.name}}
   </button>
 </div>

Working fiddle: https://jsfiddle.net/z11fe07p/547/

Upvotes: 1

Related Questions