Formatting values in Vue templates
By Flavio Copes
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:
- transforming a string, for example capitalizing it or making it lowercase
- formatting a price
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.
Want me to talk about your product? You can sponsor this site.