Using Filters in Vue.js

Avatar of Sarah Drasner
Sarah Drasner on

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.