Being able to add dynamic class names to components is a very powerful feature. It makes it easier for us to write custom themes, add classes according to the state of the component, and also write different variations of components that depend on style.
Adding dynamic class names is as simple as adding prop :class="classname" in a component. Whatever the classname evaluates, it will be the class name added to the component.
Of course, there is a lot we can do for dynamic classes in Vue. In this article, we will discuss a lot:
- Using static and dynamic classes in Vue
- How to use regular JS expressions to calculate our class
- Array syntax for dynamic class names
- Object Syntax
- Quickly generate class names
- How to use dynamic class names on custom components
Static and dynamic classes
In Vue, we can add static and dynamic classes to the component.
Static classes are tedious classes that never change, and they will always appear in the component. On the other hand, we can add and remove dynamic classes in our application.
Adding a static class is exactly the same as what you do in regular HTML
<template> <span class="description"> This is how you add static classes in Vue. </span> </template>
Dynamic classes are very similar, but we have to use Vue's special attribute syntax v-bind to bind JS expressions to our class:
<template> <span v-bind:class="'description'"> This is how you add static classes in Vue. </span> </template>
Here you will notice that we have to add extra quotes around the dynamic class name.
This is because the v-bind syntax accepts anything we pass as a JS value. Adding quotes ensures that Vue treats it as a string.
Vue also has a shorthand syntax for v-bind:
<template> <span :class="'description'"> This is how you add static classes in Vue. </span> </template>
What's really amazing is that you can even have both static and dynamic classes on the same component. Static classes are used for content that we know will not change, such as positioning and layout, dynamic classes are used for topics and so on:
<template> <span class="description" :class="theme" > This is how you add static classes in Vue. </span> </template> export default { data() { return { theme: 'blue-theme', }; } }; ---------------------------------------- .blue-theme { color: navy; background: white; }
In this case, the theme is a variable containing the class name we will apply.
Conditional class names
Since v-bind can accept any JS expression, we can do something really cool with it. My favorite is using ternary expressions in templates, which tend to be very clean and readable.
<template> <span class="description" :class="darkMode ? 'dark-theme' : 'light-theme'" > This is how you add dynamic classes in Vue. </span> </template>
If darkMode is true, use dark-theme as our class name. Otherwise, we choose light-theme.
Using array syntax
If you need to dynamically add many different classes, you can use arrays or objects. Both methods are very useful, let's first look at the array method.
Because we are just calculating a JS expression, we can combine the expression we just learned with the array syntax
<template> <span class="description" :class="[ fontTheme, darkMode ? 'dark-theme' : 'light-theme', ]" > This is how you add dynamic classes in Vue. </span> </template>
We use an array to set two dynamic class names on this element. The value of fontTheme is a class name that will change the appearance of the font. In the previous example, we can still switch between dark-theme and light-theme using the darkMode variable.
Using object syntax
We can even use objects to define lists of dynamic classes, which gives us more flexibility.
For any key/value pair that is true, it will use the key as the class name. Let's look at an example of object syntax:
<template> <span class="description" :class="{ 'dark-theme': darkMode, 'light-theme': !darkMode, ]" > This is how you add dynamic classes in Vue. </span> </template>
Our object contains two keys: dark-theme and light-theme. Similar to the logic we implemented earlier, we want to switch between these topics based on the value of darkMode.
When darkMode is true, dark-theme will be applied to our element as a dynamic class name. But light-them will not be applied because the !darkMode value is false.
Now we have covered the basics of dynamically adding classes to Vue components. So how do you do this with your own custom components?
Work with custom components
Suppose we have a custom component in the app
<template> <MovieList :movies="movies" :genre="genre" /> </template>
What should we do if we want to dynamically add a class that will change the topic? Actually very simple.
We just need to add the :class attribute as before
<template> <MovieList :movies="movies" :genre="genre" :class="darkMode ? 'dark-theme' : 'light-theme'" /> </template>
This works because Vue directly sets the class on the root element of the MovieList.
When setting props on a component, Vue compares these props with the props specified in the component's props section. If there is a match, it will be passed as regular props. Otherwise, Vue will add it to the root DOM element.
Here, since MovieList does not specify the class attribute, Vue knows that it should be set on the root element.
However, we can do something more advanced with dynamic class names.
Quickly generate class names
We have covered many different ways to dynamically add or delete class names. But what about dynamically generating class names themselves?
Suppose there is a Button component that provides 20 different CSS styles for all different types of buttons.
You may not want to spend the whole day writing out every item, nor do you want to write out the logic of the switch. Instead, we will dynamically generate the name of the class to be applied.
<template> <span class="description" :class="theme" > This is how you add static classes in Vue. </span> </template> export default { data() { return { theme: 'blue-theme', }; } }; .blue-theme { color: navy; background: white; }
We can set a variable to contain strings of any class name we want. If we want to do this with the Button component, we can do the following simple operation:
<template> <button @click="$emit('click')" class="button" :class="theme" > {{ text }} </button> </template> export default { props: { theme: { type: String, default: 'default', } } }; .default {} .primary {} .danger {}
Now anyone using the Button component can set the theme property to any theme they want to use.
If no classes are set, it will add the .default class. If you set it to primary, the .primary class is added.
Use computed properties to simplify classes
Eventually, the expressions in the template will become overly complex and will start to become very confusing and difficult to understand. Fortunately, we have an easy solution, which is to use computed people attributes:
<template> <MovieList :movies="movies" :genre="genre" :class="class" /> </template> export default { computed: { class() { return darkMode ? 'dark-theme' : 'light-theme'; } } };
Not only is this easy to read, it also makes it easy to add new features and refactor in the future.
This is the end of this article about how to dynamically add class names in Vue. For more related content on Vue, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!