Imagine that every time you have to fetch manipulated data, you need to execute a function. Imagine that you need to get specific data that needs to go through some process and you need to execute it through a function every time. This type of work would not be easy to maintain. Computed properties exist to solve these problems. Using computed properties makes it easier to obtain data that needs preprocessing or even caching without executing any other external memorizing function.
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
You 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 the Vue CLI recipe.
How to do it...
Follow these steps to create a computed property and understand how it works:
- In the App.vue file, at the <script> part, we will add a new property between data and method, called computed. This is where the computed properties will be placed. We will create a new computed property called displayList, which will be used to render the final list on the template:
<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: {
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 now, the displayList property is just returning a cached value of the variable, and not the direct variable itself.
- Now, for the <template> part, we need to change where the list is being fetched:
<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'>
{{ taskItem.finishedAt }}
</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
- To run the server and see your component, you need to open a Terminal (macOS or Linux) or Command Prompt/PowerShell (Windows) and execute the following command:
> npm run serve
How it works...
When using the computed property to pass a value to the template, this value is now cached. This means we will only trigger the rendering process when the value is updated. At the same time, we made sure that the template doesn't use the variable for rendering so that it can't be changed on the template, as it is a cached copy of the variable.
Using this process, we get the best performance because we won't waste processing time rerendering the DOM tree for changes that have no effect on the data being displayed. This is because if something changes and the result is the same, the computed property caches the result and won't update the final result.
See also
You can find out more information about computed properties at https://v3.vuejs.org/guide/computed.html.