Search code examples
htmllistvue.jsindexingv-for

vue.js / v-for: How to style html depending on list index


I have a list, of which I want to style the items in a different way, depending on their indexes:

<ul>
    <li 
    v-for="(item, index) in myList()" 
    :key="index">{{item}}
    </li>
</ul>

If item reaches index 4 and 5, I want it to be <strong>. How do I use v-if or indexof in this case the right way?

Or should I go with dynamic classes in this case?


Solution

  • There are several ways to do this:

    1. Bind a method that returns an object to the style attribute

    You can do this by binding the <li> element's style attribute to a method that accepts its index. In the method, you return a CSSStyleDeclaration object that is appropriate. For example, if i is 4 or 5, then you set fontWeight to bold:

    new Vue({
      el: '#app',
      methods: {
        myList: function() {
          return ['Lorem', 'Ipsum', 'Dolor', 'Sit', 'Amet', 'Foo', 'Bar', 'Baz'];
        },
        listItemStyle: function(i) {
          var style = {};
          
          if (i === 4 || i === 5) {
            style.fontWeight = 'bold';
          }
          
          return style;
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <ul>
        <li
          v-for="(item, index) in myList()"
          :style="listItemStyle(index)"
          :key="index">
          {{item}}
        </li>
      </ul>
    </div>

    2. Use <component> to determine if a <strong> tag should be rendered

    This is not my preferred method, since I personally prefer binding styles instead of dictating appearance using DOM elements. However, if you want to use <strong> instead of setting font-weight: bold, you can simply make use of the <component is="[tag]"> method to decide which HTML tag to be rendered in place:

    new Vue({
      el: '#app',
      methods: {
        myList: function() {
          return ['Lorem', 'Ipsum', 'Dolor', 'Sit', 'Amet', 'Foo', 'Bar', 'Baz'];
        },
        tag: function(i) {
          if (i === 4 || i === 5) {
            return 'strong';
          }
          
          return 'span';
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <ul>
        <li
          v-for="(item, index) in myList()"
          :key="index">
          <component v-bind:is="tag(index)">
            {{item}}
          </component>
        </li>
      </ul>
    </div>