Vue alternate classes in v-for

tazboy picture tazboy · Mar 25, 2017 · Viewed 10.9k times · Source

I have an array (history) that is being pushed two items every time a button is pressed. Those two items will need to have different css styles when printed.

HTML

<ul class="info">
  <li :class="{ 'style-one' : toggle, 'style-two' : toggle }" v-for="item in history">{{item}}</li>
</ul>

JS (Vue)

methods: {
  attack: function() {
  this.history.unshift(this.playerDamaged);
  this.history.unshift(this.monsterDamaged);
}

The problem with this is there is no way to change the truthiness of toggle during the loop. Is there a better way to approach this?

Answer

Happyriri picture Happyriri · Mar 25, 2017

SOLUTION 1 :

You can use this code :

<ul class="info">
  <li v-for="item in history" :key="item"
      :class="{ 'style-one' : item.isPlayer, 'style-two' : !item.isPlayer }"
      >

   {{ item.text }}

  </li>
</ul>

methods: {
  attack: function() {
  this.history.unshift({ text: this.playerDamaged, isPlayer: true });
  this.history.unshift({ text: this.monsterDamaged, isPlayer: false });
}

UPDATED - SOLUTION 2 [No use of objects] :

You can use an other solution with no objects :

<ul class="info">
  <li v-for="(item, index) in history" :key="item"
      :class="'style-' + ((index % numberOfPlayers) + 1)"
      >

   {{ item }}

  </li>
</ul>

//This part don't have to deal with Array of Objects :
methods: {
  attack: function() {
  this.history.unshift( this.playerDamaged );
  this.history.unshift( this.monsterDamaged );
},
computed: {
    numberOfPlayers: function() {
        return 2;
    }
  }

If you want to add a player (ex: monster 2) you have to update the computed numberOfPlayers to 3 (or better : listOfPlayers.length if you have) and create a class ".style-3".

Code example :

new Vue({
  el: "#app",
  data: function() {
    return {
    	myArray: ['player attack', 'monster attack','player attack', 'monster attack']
    }
  },
  computed: {
    numberOfPlayers: function() {
    	return 2;
    }
  }
});
.style-1 {
  color: blue;
}

.style-2 {
  color: red;
}
<script src="https://vuejs.org/js/vue.min.js"></script>

<div id="app">

  <div v-for="(item, index) in myArray" :key="item"
       :class="'style-' + ((index % numberOfPlayers) + 1)"
       >
      {{ item }}
  </div>

</div>