In this post, we will go through everything you need to know about Vue.js filters, from how to use them in your Vue.js application to how to create your own filters.
Filters? Like Instagram Filters? โ๐๐คณ Euh… ๐NO! Sorry.
๐ค Filters are actually a feature provided by Vue.js that lets you apply common text formatting to your data. Filters do NOT change the data itself but rather change the output to the browser by returning a filtered version of that data.
I bet that said this way you’re like, “Okay, thanks for the FYI!” But to get a sense of how useful they are, let me tell you what I most like to use them for: price formatting, capitalizing data coming from an API or even specifying some common fallback for a given variable. The list goes on and on as they can be used in a myriad of ways.
I bet I got your attention now! ๐
We will go through everything you need to know about Vue.js filters, from how to use them in your Vue.js application to how to create your own filters. ๐คชExciting, isn’t it?
๐ต๐ผThere was a time when filters were a built-in function in Vue.js. Although built-in filters were useful, they lacked flexibility. So our lord and savior, Evan You, decided to remove them from Vue 2.0. โ๐ผ So be wary, my dear friends, of old tutorials!
Now, here is how we can use filters: either in mustache interpolations Hey {{ username | capitalize }}
OR in a v-bind expression (notice the pipe in both of them).
<!-- With mustache interpolations -->
<h1>{{ article.title | uppercase }}</h1>
<!-- With v-bind expression -->
<title-component :title="article.title | uppercase" />
You can define a filter as global (available in all components) or local (only in the component it is defined in). Here is how you would define a local filter:
export default {
filters: {
capitalize: function(value) {
if (!value) {
return "";
}
value = value.toString();
return value.charAt(0).toUpperCase() + value.slice(1);
}
}
};
โ ๏ธ A local filter with the same name as a global filter will always prime.
Making your own filter is pretty easy if you understand what we’ve seen so far. But we’ll go through the steps together so you can have a clear idea of how to do it.
Because creating a local filter is pretty straightforward, we’re creating a global filter first for Vue.js and then for Nuxt.js. This filter will format an article preview text in two ways: first capitalize the first letter and then truncate the text.
Let’s get to work! ๐
Create a separate file where you store your filters. For small projects, I usually stored them in a folder named helpers
.
// src/helpers/filters.js
// NPM
import Vue from "vue";
Vue.filter("capitalize", function(value) {
if (!value) {
return "";
}
value = value.toString();
return value.charAt(0).toUpperCase() + value.slice(1);
});
Vue.filter("cutText", function(value, length, suffix) {
if (value.length > length) {
return value.substring(0, length) + suffix;
} else {
return value;
}
});
Then, just import this file in your Vue entrypoint (usually: main.js
).
// src/main.js
import "@/helpers/filters";
// ...
Remember: This is a global filter. Thus, it will be defined in every single one of your components if you do not override it with a local filter with the same name.
For Nuxt, it is not that different. We use a plugin to store them.
// plugins/filters.js
// NPM
import Vue from "vue";
Vue.filter("capitalize", function(value) {
if (!value) {
return "";
}
value = value.toString();
return value.charAt(0).toUpperCase() + value.slice(1);
});
Vue.filter("cutText", function(value, length, suffix) {
if (value.length > length) {
return value.substring(0, length) + suffix;
} else {
return value;
}
});
And we import it in our nuxt.config.js
file.
// nuxt.config.js
module.exports = {
plugins: [{ src: "@/plugins/filters.js" }]
};
But what should I do if I want to use two filters (let’s go crazy: or more) instead of just one filter? Easy peasy lemon squeezy my friends: You chain them, โ simply by repeating the pipe syntax like this: hey {{ username | fallback | capitalize }}!
โ ๏ธ Keep in mind that the order in which your filters are used is important. In the example above, we will first fetch the username, then we apply the filter
fallback
(that replaces the word username with a fallback word like “there” if we can’t retrieve a username from the API). Then, AND ONLY THEN, the filtercapitalize
will be applied.
๐ค FYI: because filters are simply JavaScript functions, you can take your filters one step further and add one argument or more to them.
In the example above, we have article.preview
as the first argument of the truncate filter (the value
). Then 200
is here to define the length
as the filter’s 2nd argument, and so on with "..."
being used as the 3rd argument as the suffix
.
<template>
<h2>{{ article.title }}</h2>
<p>{{ article.preview | capitalize | truncate(200, '...') }}</p>
</template>
<script>
export default {
data() {
return {
article: {
title: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
preview: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Feugiat vivamus at augue eget arcu dictum. Nibh ipsum consequat nisl vel pretium lectus quam id. Lobortis mattis aliquam faucibus purus in massa tempor nec feugiat. Scelerisque in dictum non consectetur. Sit amet consectetur adipiscing elit ut aliquam purus sit amet. Viverra justo nec ultrices dui sapien. Feugiat in ante metus dictum at. In massa tempor nec feugiat nisl pretium fusce id. Maecenas accumsan lacus vel facilisis volutpat est velit. Facilisis magna etiam tempor orci eu lobortis. Sit amet consectetur adipiscing elit duis. Vel risus commodo viverra maecenas accumsan. Id neque aliquam vestibulum morbi blandit.'
}
}
}
}
</script>
As we mentioned, Vue.js doesn’t have built-in filters anymore and maybe you don’t want to go through the hassle of creating your own filters. The Vue.js community has you covered as usual! ๐
Aleksandr Statciuk has made this AMAZING package that offers us 12 of the most commonly used filters.
๐ You can find even more helpful filters made by the community here in the awesome-vue GitHub repository (in the section about filters).
My homeboy Rachid Laasri (curious? ๐ it’s Rabat ) shares with us 11 more super duper Vue.js filters in his article that you can use in your project.
Another filter I use quite often is vue-moment. It will let you format your string with moment.js in a snap!
Another one I like: vue-numeral-filter. It will let you format your numbers with numeral.js.
Sometimes you have to handle complex logic and you may be using computed properties. You can still use a filter inside. It is a bit verbose, but all your filters will be available inside the this.$options.filters
object.
export default {
computed: {
formatting() {
let result = "hello ";
if (this.user) {
result += this.user.name;
} else {
result += this.generateARandomName();
}
return this.$options.filters.capitalize(result);
}
}
};
Et Voilà! ๐
๐ฉ๐ผ๐ซAs Sarah Drasner has pointed out in her article, filters are not the perfect solution to solve every problem. First, they need to rerun on every single update. Like she said, if you have something like an input that updates every time you type, it won’t be performant. A computed property will be a better fit as it will cache the results based on their dependencies and will be reevaluated only when those dependencies change.
If you have any questions, feel free to reach me in the comments below or to reach out to me on Twitter @RifkiNada. ๐ค
Nada is a JavaScript developer who likes to play with UI components to create interfaces with great UX. She specializes in Vue/Nuxt, and loves sharing anything and everything that could help her fellow frontend web developers. Nada also dabbles in digital marketing, dance and Chinese. You can reach her on Twitter @RifkiNada or visit her website, nadarifki.com.