Filters are an interesting way to deal with data rendering in Vue but are only useful in a small amount of cases. The first thing to understand about filters is that they aren’t replacements for methods, computed values, or watchers, because filters don’t transform the data, just the output that the user sees. As of Vue 2.0, there are no built-in filters, we need to construct them ourselves.
We can use filters locally or globally, but it’s worth mentioning that if you declare a Vue filter globally it should come before the Vue instance. In both cases, we would pass the value in as a parameter.
//global
Vue.filter('filterName', function(value) {
return // thing to transform
});
//locally, like methods or computed
filters: {
filterName(value) {
return // thing to transform
}
}
Filters are used with a pipe, following the piece of data you’d like to be altered upon render. So we would show the piece of data we want to alter, followed by the filter
{{ data | filter }}
Here’s a small example, with a tip calculator:
See the Pen Filters by Sarah Drasner (@sdras) on CodePen.
new Vue({
el: '#app',
data() {
return {
customer1total: 35.43
}
},
filters: {
tip15(value) {
return (value*.15).toFixed(2)
},
tip20(value) {
return (value*.2).toFixed(2)
},
tip25(value) {
return (value*.25).toFixed(2)
}
}
});
<div id="app">
<h2>Tip Calculator</h2>
<p><strong>Total: {{ customer1total }}</strong></p>
<p>15%: {{ customer1total | tip15 }}</p>
<p>20%: {{ customer1total | tip20 }}</p>
<p>25%: {{ customer1total | tip25 }}</p>
</div>
You can also use filters in v-bind
directives rather than just the mustache template. Filters can also be chained. Keep in mind if you’re going to chain filters: ordering matters. The first filter will be applied first, the second will be applied to the completed first, and so on.
{{ data | filterA | filterB }}
We can also pass additional arguments into filters like so:
{{ data | filterName(arg1, arg2) }}
// locally, like methods or computed
filters: {
filterName(value, arg1, arg2) {
return //thing to transform
}
}
Now, you might think, based on the name, that filters would be great for forms when we want to show only some bits of data and not others. However, filters need to rerun on every single update, so if you have something like an input that updates every time you type, it’s not very performant. Better to use computed
for something like this as it’s less overhead. The results will be cached based on their dependencies and won’t be rerun on every update. Computed properties will only be reevaluated when those dependencies change, but can also handle complex logic. This makes them excellent candidates for filtering information based on input. There are, however, circumstances where you do need to update based on changes in time, and for these instances, better to use a method
.
Thanks for the article. This articles acts a simple guide to reactive filtering. Idk how appropriate the term reactive filtering is
I think you’ll find that multiple parameters are now set by separating them with a space after the filter name
{{ myValue | myFilter mySecondParam }}
Also, Vue 2 supports 2 way binding of filters – specifically for user input. For more detail, it’s best to check the official docs: https://012.vuejs.org/guide/custom-filter.html
Hey! These docs are really old, these are the 0.12 docs, we’re now past version 2- these are the docs you should be looking at- make sure you check the version number.
https://vuejs.org/v2/guide/syntax.html#Filters
Old vue filters are available as separate module https://www.npmjs.com/package/vue2-filters
It has ready to use upper/lower case
truncate
filterBy
OrderBy
Pluralize
http://optimizely.github.io/vuejs.org/api/filters.html
So it is easy to include the module if our needs are fulfilled by these predefined filters
Thanks for this article! I’ve written a small helper method to add globally or locally declared filters as component methods. In this way you can use them in your component as if they were methods.
It’s a similar approach as vuex uses to map its getters or actions:
map-filters
You can use it like that:
export default {
methods: {
...mapFilters(['filterName']),
},
mounted() {
// Instead of:
const filtered = this.$options.filter.filtername(arg);
// ...you can write this:
const alsoFiltered = this.filterName(arg);
}
}