Vue filters were removed in Vue 3

The pipe syntax {{ value | filter }}, the filters component option and Vue.filter() do not exist in Vue 3. Filters were plain functions with special syntax, so the replacement is a plain function call.

Official guide: Filters, Vue 3 migration guide

Local filters

Vue 2
PriceTag.vue
<template>
  <p>{{ price | currency('EUR') }}</p>
</template>

<script>
export default {
  props: ['price'],
  filters: {
    currency(value, code) {
      return new Intl.NumberFormat('en', {
        style: 'currency', currency: code,
      }).format(value)
    },
  },
}
</script>
Vue 3
PriceTag.vue
<template>
  <p>{{ currency(price, 'EUR') }}</p>
</template>

<script>
export default {
  props: ['price'],
  methods: {
    currency(value, code) {
      return new Intl.NumberFormat('en', {
        style: 'currency', currency: code,
      }).format(value)
    },
  },
}
</script>

Note the argument order: the filtered value becomes the first argument. When the result only depends on reactive state, a computed property is even better.

Global filters

Vue 2
main.js
Vue.filter('currency', (value) =>
  '$' + Number(value).toFixed(2))

// template: {{ total | currency }}
Vue 3
main.js
const app = createApp(App)
app.config.globalProperties.$filters = {
  currency: (value) => '$' + Number(value).toFixed(2),
}

// template: {{ $filters.currency(total) }}

Chained filters

{{ name | trim | capitalize }} becomes {{ capitalize(trim(name)) }}. Read it inside out.

How vueleap detects it

vueleap reports every filter with its name and position: in interpolations and v-bind expressions (using the same scanning rules as the Vue 2 compiler, so a || b and pipes inside strings or regular expressions are ignored), in the filters option and in Vue.filter() calls. The matching compat flags are COMPILER_FILTERS (templates) and FILTERS (runtime). Filters are not rewritten automatically because global registration and argument order need a human decision.

Run it on your project:

Terminalbash
npx vueleap