Formatting values in Vue templates

By

Vue 3 removed filters. Learn how to format template values with methods and computed properties instead, with the same pipe-style formatting use cases.

~~~

In Vue 2 you could pipe a value through a filter in a template:

<p>Hi {{ name | fallback }}!</p>

Vue 3 removed filters. If you need formatting in a template, use a method or a computed property instead.

Be careful when you port old code: the template above does not fail in Vue 3. The | is read as the JavaScript bitwise OR operator, so with a string in name the template prints 0 and Vue does not complain.

A filter did not change the component data, it only affected the output. A method or a computed property does the same job, with plain function calls.

Say you are printing a name:

<template>
  <p>Hi {{ name }}!</p>
</template>

<script>
export default {
  data() {
    return {
      name: 'Flavio'
    }
  }
}
</script>

What if name is empty, and you want to print “Hi there!” instead?

With a method

<template>
  <p>Hi {{ fallback(name) }}!</p>
</template>

<script>
export default {
  data() {
    return {
      name: 'Flavio'
    }
  },
  methods: {
    fallback(value) {
      return value ? value : 'there'
    }
  }
}
</script>

Or with <script setup>:

<template>
  <p>Hi {{ fallback(name) }}!</p>
</template>

<script setup>
import { ref } from 'vue'

const name = ref('Flavio')

function fallback(value) {
  return value ? value : 'there'
}
</script>

You call the function in the template and pass it the value you want to format. That’s it.

With a computed property

If you print the same formatted value in more than one place, a computed property is the better choice:

<template>
  <p>Hi {{ displayName }}!</p>
</template>

<script setup>
import { ref, computed } from 'vue'

const name = ref('')

const displayName = computed(() => {
  return name.value ? name.value : 'there'
})
</script>

The difference is that Vue caches a computed value until name changes, while a method runs again every time the template re-renders.

Chaining and parameters

In Vue 2 you chained filters by repeating the pipe:

{{ name | fallback | capitalize }}

In Vue 3 you nest the function calls. The innermost runs first, so this applies fallback and then capitalize:

{{ capitalize(fallback(name)) }}

Filters accepted parameters too. With a function that’s just a second argument:

<template>
  <p>Hello {{ prepend(name, 'Dr.') }}</p>
</template>

<script setup>
import { ref } from 'vue'

const name = ref('House')

function prepend(value, prefix) {
  return `${prefix} ${value}`
}
</script>

Good use cases

The use cases are the same ones filters had:

If you are migrating an old Vue 2 app, search for | inside {{ }} and for filters: in the component options. Each of those becomes a method or a computed property. The vue2-filters package that shipped ready-made capitalize, currency and truncate filters is Vue 2 only, so you’ll write those small functions yourself, or put them in a shared module and import them where needed.

Tagged: Vue.js · All topics

Want me to talk about your product? You can sponsor this site.

~~~

Related posts about vue: