Home > Blockchain >  Not able to apply styles/class in vue js while using it in loop
Not able to apply styles/class in vue js while using it in loop

Time:10-04

Here is my code. item.fav is initially false, but when I click on button it becomes true, I want color of icon to be purple when item.fav is true. But this is not working.

 <template>
      <v-container fluid>
        <v-row>
         <v-col v-for="(item, index) in items">
          <v-btn icon @click='changeFav(item)'>
           <v-icon :style='{color:`${fillcolor(item)}`}'>mdi-heart</v-icon>
          </v-btn>
         </v-col>
        </v-row>
      </v-container>
    </template>
<script>
 export default {
  ....,
  methods: {
   fillcolor(item){
    return item.fav ? 'purple' : 'orange';
   },
   changeFav(item){
     item.fav=true;
   },
  }
</script>

I have also tried using class

.....
<v-icon class='{fillColor: item.fav}'>mdi-heart</v-icon>
.....

<style>
.fillColor {
color: 'purple';
}
</style>

when using a data variable as condition variable it works, but I cannot use it here as I'm having a loop.

What is that I'm doing wrong here or how can I do it better?

CodePudding user response:

Take a look at Class and Style Bindings

Here is an example

<script setup>
  import {ref} from 'vue'
const changeFav = (item) => {
     item.fav = !item.fav;
   }

const items = ref([
  {name: "test1", fav: false},
  {name: "test2", fav: false},
  {name: "test3", fav: true},
  {name: "test4", fav: false},
  {name: "test5", fav: false},
  {name: "test6", fav: false},
  {name: "test7", fav: false},
])
</script>

<template>
  <div v-for="(item, index) in items" :key="index" @click="changeFav(item)" >
    <span :class="[item.fav ? 'orange' : 'purple']">
      {{item.name}}
    </span>
  </div>
</template>

<style >
  .purple {
    color: purple;
  }
  .orange {
    color: orange;
  }
</style>

CodePudding user response:

The problem with your code is that your fillcolor method needs to run on each click, but instead you are calling the changeFav method which only triggers the item.fav and the fillcolor method never runs.

So, You need to call that function too by changing your code to this:

<v-container fluid>
      <v-row>
        <v-col v-for="(item, index) in items" :key="index">
          <v-btn icon @click="changeFav(item)">
            <v-icon :style="{ color: `${fillcolor(item)}` }">mdi-heart</v-icon>
          </v-btn>
        </v-col>
      </v-row>
    </v-container>
export default {
  ....,
methods: {
    fillcolor(item) {
      return item.fav ? "purple" : "orange";
    },

    changeFav(item) {
      item.fav = true;
      return this.fillcolor(item)
    },
  },
}

================================================================ But I would prefer to do it like this:

 <template>
  <v-app>
    <v-container fluid>
      <v-row>
        <v-col v-for="(item, index) in items" :key="index">
          <v-btn icon @click="item.fav = !item.fav">
            <v-icon :color="item.fav ? 'purple': 'red'">mdi-heart</v-icon>
          </v-btn>
        </v-col>
      </v-row>
    </v-container>
  </v-app>
</template>

Although, it really depends on the way you are handling your data. For example, if you are using vuex then you should consider using mutations. I assumed you have the items and can handle them simply like this:

export default {
  data: () => ({
    items: [
      { name: "t1", fav: false },
      { name: "t2", fav: false },
      { name: "t3", fav: false },
      { name: "t4", fav: false },
      { name: "t5", fav: false },
      { name: "t6", fav: false },
      { name: "t7", fav: false },
    ],
  }),
};
  • Related