It's sort of cool to add a class to a component.
But the real fun begins when you can conditionally bind classes — turning them on and off as you wish.
In this article we'll cover:
To refresh your memory, to bind a variable to a prop, class, or style, we use this syntax:
<template><span v-bind:class="className">Learning about conditional class bindings!</span></template>
If the value of className
is blue-text
, it will add the class .blue-text
to the span
element.
Normally we shorten the binding syntax by removing v-bind
, and we're left with just this:
<template><span :class="className">Learning more about conditional class bindings!</span></template>
But this will always apply the value of className
as a class to our span
tag.
How can we toggle this behaviour and make it conditional?
There is a cool trick using the logical &&
(AND) that allows us to conditionally apply a class:
<template><spanclass="description":class="useTheme && theme">This is how you add dynamic classes in Vue.</span></template>
This is known as a guard expression.
When useTheme
is true
, it will set the class to whatever the value of theme
is.
But how does it work?
Here we have the variable useTheme
which is a boolean, and theme
is the value of the theme class.
In Javascript, the &&
(AND) operator will short-circuit if the first value is false
.
Since both values need to be true
in order for the expression to be true
, if the first is false
there is no point in checking what the second one is, since we already know the expression evaluates to false
.
So if useTheme
is false
, the expression evaluates to false
and no dynamic class name is applied.
However, if useTheme
is true, it will also evaluate theme
, and the expression will evaluate to the value of theme
. This will then apply the value of theme
as a classname.
We can do a similar trick with ternaries.
If you aren't familiar, a ternary is basically a short-hand for an if-else statement.
They look like this:
const result = expression ? ifTrue : ifFalse;
Sometimes though, we'll format them like this for readability:
const result = expression? ifTrue: ifFalse;
If expression
evaluates to true
, we get ifTrue
. Otherwise we will get ifFalse
.
Their main benefit is that they are concise, and count as only a single statement. This lets us use them inside of our templates.
Ternaries are useful if we want to decide between two different values inside of the template:
<template><spanclass="description":class="darkMode ? 'dark-theme' : 'light-theme'">This is how you add dynamic classes in Vue.</span></template>
If darkMode
is true
, we apply dark-theme
as our class name. Otherwise we choose light-theme
.
Sometimes the logic needed to decide what class name to apply is a little more complicated.
In these cases, it doesn't really fit that nicely inside of the template, and instead you want to put it into a computed prop:
<template><span :class="computedClass">We've learned so much about conditional class bindings!</span></template>
export default {computed: {computedClass() {let className = 'default';// More complicated logic to determine what// class should be appliedreturn className;}}}
Computed props are the real workhorse of Vue. In my opinion, most of your logic should be inside of computed props.
There are tons of other ways to apply classes conditionally in Vue.
To apply more than one class at a time, you can:
I cover these, as well as generating class names on the fly, in this in-depth article.