Create a global filter in Vue 3 using TypeScript

Viewed 3573

I'm following this course on Udemy but its content is outdated so I can't follow the same steps that the author has followed to create a global filter.

Also it looks like from Vue 3 documentation, filters are no longer supported.

What I'm trying to do here is fairly simple, it just needs to take a price as a number and return it as string dollar price, for eg: take 100 and return $100.

This doesn't work for me. My main.ts looks like this:

import { createApp } from "vue";
import { Vue } from 'vue-class-component';
import { viewDepthKey } from "vue-router";
import App from "./App.vue";
import router from "./router";
import store from "./store";

Vue.filter('price', function(input: number){
  if(isNaN(input)){
    return "-";
  }
  return '$' + input.toFixed(2);
})

createApp(App)
  .use(store)
  .use(router)
  .mount("#app1");

This is the error:

src/main.ts:8:5
TS2339: Property 'filter' does not exist on type 'VueConstructor<Vue<unknown, {}, {}>>'.
     6 | import store from "./store";
     7 |
  >  8 | Vue.filter('price', function(input: number){
       |     ^^^^^^
     9 |   if(isNaN(input)){
    10 |     return "-";
    11 |   }

This is how I'm trying to use it in the template:

{{ item.product.price | price }}

Is there a way to make it work or should I be using some computed property?

EDIT for a follow up question:

My class looks like this:

<script lang="ts">
import { Options, Vue } from "vue-class-component";
import { IProductInventory } from "@/types/Product";
import format from "@/helpers/format";

@Options({
    name: "Inventory",
    components: {}
})
export default class Inventory extends Vue{
    inventory:IProductInventory[] = //Coming from an api call
}
</script>

Thank you!

2 Answers

in ./helpers/filters.ts

const filters = {
  price(input: number) {
    if (isNaN(input)) {
      return "-";
    }
    return '$' + input.toFixed(2);
  }
}
export default filters;

install it globally where you create your app...

import filters from './helpers/filters'

const app = createApp(App);
app.config.globalProperties.$filters = filters
app.mount('#app')

then just do

{{ $filters.price( price ) }}

filter option is removed in Vue 3, so you could use a computed property that returns a function with parameter :

    get formatPrice(): string{
        return (price)=>{
             if(isNaN(input)){
               return "-"
             }else{
              //return other value
              }
      }
   }

instead of {{ item.product.price | price }} you'll have :

{{ formatPrice(item.product.price) }}
Related