Menu Close

Add a Conditional Class to a Vue Component

We can conditionally add classes to a Vue component by using the v-bind:class directive. The shorthand for that is :class.

For instance, we can add it as follows:

<template>
  <div id="app">
    <button @click="isRed = !isRed">Toggle</button>
    <div :class="{red: isRed, green: !isRed}">foo</div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return { isRed: false };
  }
};
</script>

<style>
.red {
  color: red;
}

.green {
  color: green;
}
</style>

In the code above, we have:

:class="{red: isRed, green: !isRed}"

to set the class according to the value of isRed. Since it’s false initially, the green class will be applied. Then when we click the Toggle button for the first, isRed becomes true, so the red class will be applied.

In the style section, we specified that the red class has color red and green class has color green, so the div’s text will toggle between red and green as we click the button.

We can move the object to a computed property so that our template won’t have too much code. To do that we can write the following:

<template>
  <div id="app">
    <button @click="isRed = !isRed">Toggle</button>
    <div :class="classObj">foo</div>
  </div>
</template>

<script>
export default {
  name: "App",
  computed: {
    classObj() {
      return { red: this.isRed, green: !this.isRed };
    }
  },
  data() {
    return { isRed: false };
  }
};
</script>

<style>
.red {
  color: red;
}

.green {
  color: green;
}
</style>

We moved the object that passed into the :class directive to the function inside the computed property as follows:

classObj() {
  return { red: this.isRed, green: !this.isRed };
}

The value of classObj will update when this.isRed is updated, so we’ll get the same result as before.

In both examples, we have one conditional class applied to the div in our Vue component at one time.

Array Syntax

We can also define an array of classes, with the class names as the entries of the array. The condition for which the class is applied will be in the data object as the value of the properties with the given class names.

For instance, we can write the following code to do that:

<template>
  <div id="app">
    <button @click="isRed = !isRed">Toggle</button>
    <div :class="[isRed ? red: '', !isRed ? green: '']">foo</div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return { isRed: false, red: "red", green: "green" };
  }
};
</script>

<style>
.red {
  color: red;
}

.green {
  color: green;
}
</style>

In the code above, we have:

{ isRed: false, red: "red", green: "green" }

to place the class names as variables. Then we conditionally apply them by writing:

[isRed ? red: '', !isRed ? green: '']

in the template. Therefore, we’ll see the same result as before since the conditions and classes are the same as before. It’s just that we used the array syntax instead of the object syntax.

Conditionally Applying Classes With Vue Components

We can apply the :class directive directly on our own components or 3rd party ones. To do that, we use the same syntax. For instance, we can write the following code to do that:

components/Foo.vue:

<template>
  <p>foo</p>
</template>

App.vue:

<template>
  <div id="app">
    <button @click="isRed = !isRed">Toggle</button>
    <Foo :class="[isRed ? red: '', !isRed ? green: '']"/>
  </div>
</template>

<script>
import Foo from "./components/Foo.vue";

export default {
  name: "App",
  components: {
    Foo
  },
  data() {
    return { isRed: false, red: "red", green: "green" };
  }
};
</script>

<style>
.red {
  color: red;
}

.green {
  color: green;
}
</style>

The classes we applied conitionally will still be applied to the roo element of Foo automatically.

We can also do the same with the object syntax as follows:

App.vue:

<template>
  <div id="app">
    <button @click="isRed = !isRed">Toggle</button>
    <Foo :class="classObj"/>
  </div>
</template>

<script>
import Foo from "./components/Foo.vue";

export default {
  name: "App",
  components: {
    Foo
  },
  computed: {
    classObj() {
      return { red: this.isRed, green: !this.isRed };
    }
  },
  data() {
    return { isRed: false, red: "red", green: "green" };
  }
};
</script>

<style>
.red {
  color: red;
}

.green {
  color: green;
}
</style>

They both get the same results.

Conclusion

We can apply a class conditionally with the :class or v-bind:class directive. We can set the value of it as an object or an array.

To make our template cleaner, we can put our class code in a computed property so that it’ll be updated when any piece of component data updates.

A conditional class can be applied to elements and components alike.

Posted in vue