Search code examples
vue.jsv-for

Vue alternate classes in v-for


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?


Solution

  • 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>