Sometimes, you may find that the user, or even you, cannot read the Unix timestamp or other DateTime formats. How can we solve this problem? When rendering the data in Vue, it's possible to use what we call filters.
Imagine a series of pipes that data flows through. Data enters each pipe in one shape and exits in another. This is what filters in Vue look like. You can place a series of filters on the same variable so that it gets formatted, reshaped, and ultimately displayed with different data while the code remains the same. The code of the initial variable is immutable in those pipes.
Getting ready
The prerequisite for this recipe is Node.js 12+.
The Node.js global objects that are required for this recipe are as follows:
- @vue/cli
- @vue/cli-service-global
We can continue with our to-do list project or create a new Vue project with the Vue CLI, as we learned in the Creating your first project with Vue CLI recipe.
How to do it...
Follow these steps to create your first custom Vue filter:
- In the App.vue file, at the <script> part, in the methods, create a formatDate function inside this property. This function will receive value as a parameter and enter the filter pipe. We can check if the value is a number because we know that our time is based on the Unix timestamp format. If it's a number, we will format based on the current browser location and return that formatted value. If the value is not a number, we just return the passed value:
<script>
import CurrentTime from './components/CurrentTime.vue';
import TaskInput from './components/TaskInput.vue';
export default {
name: 'TodoApp',
components: {
CurrentTime,
TaskInput
},
data: () => ({
taskList: []
}),
computed: {
displayList() {
return this.taskList;
}
},
methods: {
formatDate(value) {
if (!value) return '';
if (typeof value !== 'number') return value;
const browserLocale =
navigator.languages && navigator.languages.length
? navigator.languages[0]
: navigator.language;
const intlDateTime = new Intl.DateTimeFormat(
browserLocale,
{
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric'
});
return intlDateTime.format(new Date(value));
},
addNewTask(task) {
this.taskList.push({
task,
createdAt: Date.now(),
finishedAt: undefined
});
},
changeStatus(taskIndex) {
const task = this.taskList[taskIndex];
if (task.finishedAt) {
task.finishedAt = undefined;
} else {
task.finishedAt = Date.now();
}
}
}
};
</script>
- For the <template> part of the component, we need to pass the variable to the filter method. To do this, we need to find the taskItem.finishedAt property and make it the parameter of the formatDate method. We will add some text to denote that the task was Done at: at the beginning of the date:
<template>
<div id='app'>
<current-time class='col-4' />
<task-input class='col-6' @add-task='addNewTask' />
<div class='col-12'>
<div class='cardBox'>
<div class='container'>
<h2>My Tasks</h2>
<ul class='taskList'>
<li
v-for='(taskItem, index) in displayList'
:key='`${index}_${Math.random()}`'
>
<input type='checkbox'
:checked='!!taskItem.finishedAt'
@input='changeStatus(index)'
/>
{{ taskItem.task }}
<span v-if='taskItem.finishedAt'> |
Done at:
{{ formatDate(taskItem.finishedAt) }}
</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
- To run the server and see your component, open a Terminal (macOS or Linux) or Command Prompt/PowerShell (Windows) and execute the following command:
> npm run serve
Here is the component rendered and running:
How it works...
Filters are methods that receive a value and must return a value to be displayed in the <template> section of the file, or used in a Vue property.
When we pass the value to the formatDate method, we know that it's a valid Unix timestamp, so it's possible to invoke a new Date class constructor, passing value as a parameter because the Unix timestamp is a valid date constructor.
The code behind our filter is the Intl.DateTimeFormat function, a native function that can be used to format and parse dates to declared locations. To get the local format, we can use the navigator global variable.
See also
You can find out more information about Intl.DateTimeFormat at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat.