Filters in VueJS allow you to apply text formatting in mustache interpolations. Filters should be appended to the javascript expression, denoted by the "pipe" symbol.

That is a fancy way of saying filters allow you to apply text formatting to your components model values. Do you have a date object and you want to make sure it always follows a certain format? Create a filter for it. Do you have a numeric value you want to display as a currency with a dollar sign and ensure it is displayed to two decimal places? Create a filter for it.

A  simple filter

Filters, defined in your components options, are simply javascript functions that accepts a value and returns a string. Here is a very simple filter using moment.js to format a date:

<!-- use dayFormat to have momentjs dayFormat value -->
{{ myDate | dayFormat }}
filters: {
	dayFormat (value) {
		return new moment(value).format('Do')
	}
}

Assuming a valid date is passed it would return the day of the month (1st, 2nd, 3rd, etc).

Filters with Parameters

However, since a filter is just a function it is also possible to pass multiple parameters. As an example, the smarter way to write the above filter would be to pass an additional parameter that would tell Moment.js how the date should be formatted.

<!-- call the moment filter and pass in a format -->
{{ myDate | moment('LLLL') }}
filters: {
	moment (value, format) {
		return new moment(value).format(format)
	}
}

As you can see, the value parameter passed to our filter is implied, we just need to provide the extra format parameter. I now have a generic filter that can handle multiple date formats. I used Moment.js in this example, but this can be applied to other libraries where you might want to output formatted data.

No this Scope

Another issue I ran up against when I first got in to Vue is the fact that filters do not have access to your components this scope. All data required for the filter must be passed in as a paramter.

Imagine you are working on a blog and your component has model data for authors containing an id and name and for posts an author_id and title. When you displaying posts an author_id would not be that helpful for someone reading your blog, but the authors name would be.

In this instance, the filter takes a parameter of authors which it will use for getting the name of the post author. It is a minor thing, but trying to access this.authors inside the filter would cause an error.

<!-- mustache -->
<table>
  <thead>
    <tr>
      <th>Author</th>
      <th>Title</th>
    </tr>
  </thead>
  <tr v-for="post in posts" :key="post.id">
    <td>{{ post.author_id | authorLookup(authors) }}</td>
    <td>{{ post.title }}</td>
  </tr>
</table>
data () {
  return {
    authors: [
      { id: 1, name: 'Rob' },
      { id: 2, name: 'Todd' },
      { id: 3, name: 'Ray' }
    ],
    posts: [
      { id: 1, author_id: 3, title: "Want A Thriving Business? Focus On kittens!"},
      { id: 2, author_id: 2, title: "3 Ways To Have (A) More Appealing kitten"},
      { id: 3, author_id: 1, title: "How To Lose Money With Cats"},
      { id: 4, author_id: 1, title: "What Your Customers Really Think About Your Cats?"},
      { id: 5, author_id: 3, title: "3 Ways To Master Cats Without Breaking A Sweat"},
      { id: 6, author_id: 2, title: "Death, Cats And Taxes"},
      { id: 7, author_id: 1, title: "3 Simple Tips For Using Cats To Get Ahead Your Competition"}
    ]
  }
},
filters: {
  authorLookup (value, authors) {
    return authors.filter((author) => {return author.id === value})[0].name
  }
}

Wrapping it all up

Filters make it incredibly easy and fast to programmatically format text. Hopefully you will find this post useful as these are some of the items that tripped me up when I was first getting in to Vue.

Here is a Codepen covering all of these examples.

Filter Examples