Creating a rainbow in Vue using v-for

This post will cover:

  • A brief overview of v-for
  • Using v-for to display items from an array
  • Adding alternating colors to the items
  • Adding multiple colors to the items

Note: I'll be using <template> syntax for all code snippets here

Demo

Example of the final components that will be covered:

Codesandbox

V-for Intro

Within Vue, often you will find yourself wanting to display a list of items. Vue has an elegant solution which allows you to repeat an HTML block utilizing the v-for directive (Vue's v-for Full Documentation).

This is what a general template for v-for would look like for an array of item objects:

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

Which will look like this:

Codesandbox

Three points to note about this code snippet:

  1. index doesn't need to be imported, but doing so will enable you to easily reference where in the array the current item is .
  2. Often v-bind: will be shortened to simply :. In this case v-bind:key="index" can be written as :key="index"
  3. The key is used as an identifier for Vue so that if an item in your list needs to be re-rendered, it can update only the specific item(s) that need it instead of the entire list every time!

For a more detailed introduction to v-for, I highly recommend checking here:

Hands on Vue.js for Beginners part 4

Building the Components

Now that we have a list of items displayed (see above example) we'll add static CSS (which we will build upon in future components).

Static Color Component

Before we get into the fancy work, we are going to start with the basics. Due to what we will be doing in the next two components, we're going to add the following to our <li> element:

<li
    v-for="(item, index) in itemList"
    v-bind:key="index"
+   v-bind:style="{
+       backgroundColor: 'firebrick',
+       color: 'white'
+   }"
>

// I also added the following to the to make it feel less dense //
<style>
+li {
+  padding: 5px;
+}
</style>

Let's review our changes line by line:

v-bind:style="{ - This creates a vue binding for style, which allows us to reference our data and/or item values for setting our style. In this case, we will be using Object Syntax.

backgroundColor: 'firebrick', - Vue uses camelCase for CSS properties instead of kebab-case. For now, we are statically setting our property value to 'firebrick'

color: 'white' - Similar to background color, we are statically assigning our font color to 'white'.

}" - Close our object!

At this point, our component will look like this:

Codesandbox

Alternating Colors Component

Now, let's spice it up and alternate colors! For the first example, we're going to alternate between rebeccapurple (#663399) and firebrick (#B22222) using an array with our colors. For demonstration purposes, I'll be mixing a hexcode with a CSS color name.

<template> updates:

<li
    v-for="(item, index) in itemList"
    v-bind:key="index"
    v-bind:style="{
-       backgroundColor: 'firebrick',
+       backgroundColor: colors[index % 2],
        color: 'white'
    }"
>

<script> updates:

data() {
    return {
-       itemList: ["Item A", "Item B", "Item C", "Item D", "Item E"]
+       itemList: ["Item A", "Item B", "Item C", "Item D", "Item E"],
+       colors: ["rebeccapurple", "#B22222"]
    };
}

Line by line review:

colors: ["rebeccapurple", "#B22222"] - Create an array of colors we would like to cycle through for our background color. Note that unlike in CSS, these need to be wrapped in " to set the values as a string.

backgroundColor: colors[index % 2]

  • index % 2 - If you've never seen the Modulo (or Remainder) operator before, this might look strange to you. What happens here is the number after the % is removed from the number before it until it cannot be subtracted out and result in a non-negative number.

i.e) 7 % 3 => 7 - 3 = 4 => 4 - 3 = 1 => 3 cannot be removed from 1, so 7 % 3 will return 1

  • backgroundColor: colors[index % 2] - The background color will be set based on what value is returned from our colors array. In this case, colors[0] will return rebeccapurple and colors[1] will return #B22222.

Current State: Codesandbox

Rainbow Component

Now that we have our alternating colors setup, we can make 2 minor tweaks to our code to alternate through as many colors as we want!

<template>

<li
    v-for="(item, index) in itemList"
    v-bind:key="index"
    v-bind:style="{
-       backgroundColor: colors[index % 2],
+       backgroundColor: colors[index % colors.length],
        color: 'white'
    }"
>

<script> updates:

data() {
    return {
-       itemList: ["Item A", "Item B", "Item C", "Item D", "Item E"],
+       itemList: ["Item A", "Item B", "Item C", "Item D", "Item E","Item A", "Item B", "Item C", "Item D", "Item E"],
-       colors: ["rebeccapurple", "#B22222"]
+       colors: ["rebeccapurple", "#B22222", "black", "navy", "green"]
    };
}

Line by line review:

colors[index % colors.length]

Here, we replaced 2 with colors.length which will use the length of our colors array to determine how many colors we would like to cycle through.

itemList: ["Item A", "Item B", "Item C", "Item D", "Item E","Item A", "Item B", "Item C", "Item D", "Item E"]

Here, I'm doubling the list of items for demonstration purposes ๐Ÿ˜‰

colors: ["rebeccapurple", "#B22222", "black", "navy", "green"]

This adds black, navy, and green to our list of colors to cycle through.

Final State: Codesandbox

Closing Remarks

This post is brought to you by my work on https://gridsomeairtable.netlify.com/ where I'm using this technique on the Events page to cycle through the yellow, blue, and red borders!

GitHub: Gridsome-Airtable-Starter

If you use this technique somewhere, I'd love if you would comment below or tweet a link to me so I can check it out!

๐Ÿงช Experiment ๐Ÿงช | ๐Ÿ’ฅ Fail ๐Ÿ’ฅ | ๐Ÿง  Learn ๐Ÿง 
ยฉ 2024, Built with Nuxt