En Vue.js, una computed property es una propiedad que se calcula dinámicamente en función de otras propiedades reactivas.
Nos permiten calcular valores derivados de manera reactiva. Es decir, valores que dependen de otros datos, y que se actualizan automáticamente cuando esos datos cambian.
Por ejemplo
- Transformar datos: Por ejemplo, formatear una fecha o filtrar una lista.
- Calcular valores derivados: Por ejemplo, calcular el total de un carrito de compras.
Las computed properties son reactivas, lo que significa que se actualizan automáticamente cuando sus dependencias cambian.
Además se cachean (almacenan en caché), por lo que solo se recalculan cuando sus dependencias cambian. Es decir, que son eficientes para cálculos costosos o repetitivos.
Sintaxis básica de las computed properties
En la Composition API, las computed properties se definen utilizando la función computed
, que se importa desde el paquete vue
.
La función computed
recibe un getter (una función que devuelve el valor calculado) y devuelve una referencia reactiva.
Vamos a verlo con un ejemplo sencillo, como calcular el cuadrado de un número
<template>
<div>
<p>Número: {{ numero }}</p>
<p>Cuadrado: {{ cuadrado }}</p>
<button @click="incrementar">Incrementar</button>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
const numero = ref(2);
// Computed property para calcular el cuadrado del número
const cuadrado = computed(() => {
return numero.value * numero.value;
});
function incrementar() {
numero.value++;
}
</script>
En este ejemplo,
cuadrado
es una computed property que depende denumero
- Cada vez que
numero
cambia,cuadrado
se recalcula automáticamente.
Computed properties con setter
Por defecto, las computed properties son de solo lectura. Es decir, que si intentas asignar un valor a una computed property, Vue.js lanzará un error.
Sin embargo, también es posible crear computed properties con un setter (si es necesario).
Vamos a verlo con un ejemplo, donde calculamos el nombre completo
, a partir del nombre
y apellido
<template>
<div>
<p>Nombre completo: {{ nombreCompleto }}</p>
<input v-model="nombre" placeholder="Nombre" />
<input v-model="apellido" placeholder="Apellido" />
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
const nombre = ref('Juan');
const apellido = ref('Pérez');
// Computed property con getter y setter
const nombreCompleto = computed({
get() {
return `${nombre.value} ${apellido.value}`;
},
set(valor) {
const [nuevoNombre, nuevoApellido] = valor.split(' ');
nombre.value = nuevoNombre;
apellido.value = nuevoApellido;
},
});
</script>
En este ejemplo,
nombreCompleto
es una computed property con un getter y un setter- El
getter
devuelve el nombre completo - El
setter
divide el valor en nombre y apellido
Ejemplos prácticos
Filtrar una lista
Supongamos que tenemos una lista de tareas y queremos filtrar las tareas completadas.
<template>
<div>
<h2>Tareas completadas</h2>
<ul>
<li v-for="tarea in tareasCompletadas" :key="tarea.id">
{{ tarea.texto }}
</li>
</ul>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
const tareas = ref([
{ id: 1, texto: 'Aprender Vue.js', completada: true },
{ id: 2, texto: 'Hacer la compra', completada: false },
{ id: 3, texto: 'Escribir un artículo', completada: true },
]);
// Computed property para filtrar las tareas completadas
const tareasCompletadas = computed(() => {
return tareas.value.filter(tarea => tarea.completada);
});
</script>
En este ejemplo, tareasCompletadas
es una computed property que filtra las tareas completadas. Si tareas
cambia, tareasCompletadas
se recalcula automáticamente.
Calcular el total de un carrito de compras
Supongamos que tenemos un carrito de compras y queremos calcular el total.
<template>
<div>
<h2>Carrito de compras</h2>
<ul>
<li v-for="producto in carrito" :key="producto.id">
{{ producto.nombre }} - ${{ producto.precio }}
</li>
</ul>
<p>Total: ${{ total }}</p>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
const carrito = ref([
{ id: 1, nombre: 'Camiseta', precio: 20 },
{ id: 2, nombre: 'Pantalón', precio: 40 },
{ id: 3, nombre: 'Zapatos', precio: 60 },
]);
// Computed property para calcular el total del carrito
const total = computed(() => {
return carrito.value.reduce((sum, producto) => sum + producto.precio, 0);
});
</script>
En este ejemplo, total
es una computed property que calcula el total del carrito de compras. Si carrito
cambia, total
se recalcula automáticamente.