My FeedDiscussionsHeadless CMS
New
Sign in
Log inSign up
Learn more about Hashnode Headless CMSHashnode Headless CMS
Collaborate seamlessly with Hashnode Headless CMS for Enterprise.
Upgrade ✨Learn more
Improving Vuejs Apps with Vue Filters and its Alternative (Vue Computed Properties)

Improving Vuejs Apps with Vue Filters and its Alternative (Vue Computed Properties)

Sunil Joshi's photo
Sunil Joshi
·Aug 7, 2020·

8 min read

Filters

Filters are basically JavaScript functions that can be used to transform some output in the template. They take the value to be transformed as the first parameter then return the formatted version of that value.

Vuejs does not support a built-in filter so we have to build our filters depending on the task we want to accomplish.

In this article, we will build a filter that will transform data on the template from lowercase to uppercase. Also, we assume that your project is a single page application.

In Vue.js, there are two ways to register filters:

  1. Globally

  2. Locally.

The former gives you access to your filter across all your components, unlike the latter which only allows you to use your filter inside the component it was defined in.

Looking for Vuejs Templates?

  • Try our Vuejs Templates and create stunning web applications for unlimited client projects and personal projects.
  • Start building web applications and products using our Free Vuejs Templates without any investment.

Global Filters

To register a filter globally, in the main.js file the filter registration must always be above the main Vue instance, else you will get a “Failed to resolve filter: toUppercase” error.

// FILTER REGISTERATION
Vue.filter('toUpperCase', function (value) {
return ${value.toUpperCase()};
});
new Vue({
render: h => h(App),
}).$mount('#app')

Usage

In the component where we need to use the filter, the template should be:

<template>
    <div id="filter-component">
        <h1>Vuejs filters</h1>
        <span>{{ message | toUppercase }}</span>
    </div>
</template>
<script>
export default {
    data(){
        return {
            message: "welcome to vue filters"
        }
    }
}
</script>

With that our template should render the following:

Vue Filter

So in the template, we passed the message through the pipe symbol to the toUpperCase filter method for transformation where all the string value is transformed to upperCase and finally the returned value is rendered on the template.

Local Filters

Local filters are registered to a Vue component scope. In the component where we need to use the filter, we need to create our filters and use them there. Let’s illustrates how they are created:

<template>
    <div id="filter-component">
        <h1>Vuejs filters</h1>
        <span>{{ message | replace }}</span>
    </div>
</template>

<script>
export default {
    data(){
        return {
            message: "welcome to vue filters"
        }
    },
    filters: {
       // Filter definitions
        replace(value) {
            return value.replace("welcome", "Introduction");
        }
    }
}
</script>

Just like filters in angular, the pipe symbol allows the message value in the template to pass through the replace method as a parameter while the replace method returns the transformed value to the template.

With that our template should render the following:

Vuejs Filters

So in the template, we passed a message through the pipe symbol to the replace filter method for transformation where “welcome” is replaced with “Introduction” after which the returned value is rendered in the template

Chaining Filters

Another special feature of Filters is the ability to chain them using the pipe ( | ) symbol and run a single value through a series of filter methods for transformation.

Let’s chain our global filter to the local filter.

The component where we need to chain our filters:

<template>
    <div id="filter-component">
        <h1>Vuejs filters</h1>
        <span>{{ message | replace | toUppercase }}</span>
    </div>
</template>

Remember the reverse filter was declared locally while toUppercase was declared globally.

With that our template should render the following:

Vue Filters

So in the template, we passed a message through the pipe symbol to the replace filter method for transformation where “welcome” is replaced with “Introduction” after which the returned value is passed through the second pipe symbol to the toUpperCase filter method for transformation where all the string value is transformed to upperCase and finally the returned value is rendered in the template.

In vue 2.x filters have been limited in what they can do in order to avoid some optimization issues especially when handling some complex logic. This is where computed properties are a great alternative to filters.

Let’s assume we want to filter some fruits from a list of fruits when the input field is populated. We could be tempted to use filters but using filters for this task will be suboptimal from vue.js performance perspective. Hence computed property is the most suited alternative.

Vue Computed properties

Computed properties can be used to do quick calculations of properties that are displayed in the view. These calculations will be cached and will only update when needed.

Computed properties are like methods but with some difference in comparison to methods. In the case of method, we call it as a function, and for computing as a property.

For instance with computed property we can render the current date in the template by calling the getCurrentdate function without the bracket “()” as seen in the code snippet below:

<template>
  <div id="app" style="text-align: center">
    <h1>Vuejs computed property</h1>
    <h3>getCurrentdate</h3>
  </div>
</template>
<script>
export default {
  computed: {
    getCurrentdate() {
      var today = new Date();
      var dd = String(today.getDate()).padStart(2, '0');
      var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
      var yyyy = today.getFullYear();

      today = mm + '/' + dd + '/' + yyyy;
      return today;
    }
  },
}
</script>

In order to achieve the same task using methods we have to call the getCurrentdate function with a bracket as seen in the code snippet below:

<template>
  <div id="app" style="text-align: center">
    <h1>Vuejs computed property</h1>
    <h3>{{getCurrentdate()}}</h3>
  </div>
</template>
<script>
export default {
  methods: {
    getCurrentdate() {
      var today = new Date();
      var dd = String(today.getDate()).padStart(2, '0');
      var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
      var yyyy = today.getFullYear();

      today = mm + '/' + dd + '/' + yyyy;
     return today;
    }
  },
}
</script>

The content of the app.js file should be replaced with the following:

<template>
  <div id="app" style="text-align: center">
    <h1>Vuejs computed property</h1>
    <input type="text" v-model="search">
    <ul>
      <li v-for="fruit in fruits " :key="fruit">{{fruit }}</li>
    </ul>
  </div>
</template>
<script>
export default {
  data() {
    return {
      fruits: ["banana", "apple", "orange", "pea"],
      search: ''
    }
  }
}
</script>
<style>
</style>

The input value is bound to the data property using the v-model vuejs directive.

With this, our search filter is still not functional as we have the list of fruits rendered using the vue.js v-for directive.

In order to implement a functional search filter, we will use the computed property to implement the logic to handle the search functionality.

Finally, our Computed.js file should be as follow:

<template>
  <div id="app" style="text-align: center">
    <h1>Vuejs computed property</h1>
    <input type="text" v-model="search">
    <ul>
      <li v-for="fruit in filterFruit " :key="fruit">{{fruit }}</li>
    </ul>
  </div>
</template>
<script>
export default {
  data() {
    return {
      fruits: ["banana", "apple", "orange", "pea"],
      search: ''
    }
  },
  computed: {
    filterFruit() {
      if(this.search){
        return this.fruits.filter((fruit)=>{
          return this.search.toLowerCase().split(' ').every(item => item.toLowerCase().includes(item))
        })
      }else{
        return this.fruits;
      }
    }
  },
}
</script>
<style>
</style>

We have a filterFruit() function in the computed object which returns a new array of fruits that contains the current value of the input field if the input field has any value otherwise it returns the original fruits array.

With that, we now have a functional and optimized search filter using the computed property.

Conclusion

I hope you have found a useful application of filters for your vue.js applications and you now know how to create and use filters. Also, we have a better alternative to filters when it comes to handling calculations of properties that are displayed in the view. Now go ahead and refactor your previous vuejs codebase to incorporate filters and computed properties where necessary as this is a good way to practice new concepts.

Happy Coding…!! 🙂