seyet
seyet

Reputation: 1150

Vuejs, change a button color in a list when its clicked

I have a list of buttons that I populate using an array of objects:

          <div
            class="form-inline"
            v-for="(genre, index) in genreArray"
            :key="index"
          >
            <button class="btn m-1" type="button" @click="genreButton(genre, index)" 
                :class="[
                  { 'clicked': clicked}
                ]"
            >
              {{ genre.name }}
            </button>
          </div>

The array has this format:

genreButton=[{
  id='1234'
  name='buttonOne'
},
//and many more objects with same key and different values
]

I try to change color of a button that is clicked by adding a class to it:

data(){
  return {
    clicked: false  
  }
},
methods:{
  genreButton(genre, index){
    this.clicked = !this.clicked
  }
}

and this is the CSS:

.clicked{
  background-color= red;
}

But the issue is when I do it all the buttons change color. How can I ONLY change the color of the button that is clicked?

Upvotes: 0

Views: 2039

Answers (1)

Maxime Moreillon
Maxime Moreillon

Reputation: 321

Here, clicked is a component-level property and as such it is shared by all buttons within it.

One solution would be to have a property called clicked for each button of the genreButton array:

genreButton=[
  {
    id:'1234'
    name:'buttonOne'
    clicked: false,
  },
  //...
]

However, a more elegant approach could be to create a dedicated component for the buttons with an internal clicked property.

<template>
  <button 
    class="btn m-1" 
    type="button" 
    @click="clicked = !clicked" 
    :class="[ { 'clicked': clicked} ]" >
    {{ genre.name }}
  </button>
</template>

<script>
export default {
  name: 'CustomButton',
  props: {
    genre: Object,
  },
  data: () => ({
    clicked: false,
  })
}
</script>

<style scoped>
.clicked{
  background-color= red;
}
</style>

You can then use your button component as so:

<div
  class="form-inline"
  v-for="(genre, index) in genreArray"
  :key="index" >
  <CustomButton :genre="genre" />
  
</div>

Upvotes: 2

Related Questions