Las propiedades computadas en Vue con el Composition API permiten reemplazar watchers innecesarios y simplificar la lógica reactiva. Aquí verás cómo usar la función computed para derivar valores como el color del precio según stock y el total del carrito, manteniendo el código claro, predecible y fácil de mantener.
¿Cómo crear propiedades computadas con Composition API?
Para crear una propiedad computada en Composition API se importa la función computed desde Vue y se define una función que depende de datos reactivos. Si esas dependencias cambian, la propiedad se recalcula automáticamente.
Importar y definir con función pura.
Basar el cálculo en dependencias reactivas.
Exponer la variable cuando no está dentro de reactive.
¿Qué hace computed y cuándo se recalcula?
La función computed recibe una función que usa dependencias reactivas. Si alguna cambia (por ejemplo, el stock del producto), el valor computado se actualiza sin necesidad de un watcher manual.
Ejemplo como variable independiente (se debe retornar en el estado):
import{ computed }from'vue'const priceColor =computed(()=>{// si el stock es menor o igual a 1: rojo, si no: azulreturn props.product.stock<=1?'red':'blue'})// ...luego exponerla en el return del setupreturn{ priceColor }
¿Cómo exponer la propiedad en el estado?
Si la propiedad computada se crea como variable (fuera de reactive), hay que retornarla en el estado del componente. Esto reemplaza al watcher que antes modificaba el color del precio y mantiene la lógica declarativa.
¿Cómo definir computed dentro de reactive?
También se puede definir la propiedad computada directamente dentro de un objeto reactive. En este caso, no necesitas retornarla por separado porque ya forma parte del estado.
Declaración inline con operador ternario.
Menos código repetido al no retornarla explícitamente.
Lectura directa desde el estado reactivo.
Ejemplo dentro del estado del producto:
import{ reactive, computed }from'vue'const productState =reactive({// otras propiedades del producto...priceColor:computed(()=>(props.product.stock<=1?'red':'blue')),})// productState ya se retorna, no hace falta exponer priceColor aparte
Beneficios clave:
Menos boilerplate al integrar la lógica en el estado.
Reactividad predecible: se recalcula según sus dependencias.
Legibilidad: la intención queda cerca de los datos.
¿Cómo calcular el total del carrito con una propiedad computada?
El watcher general que observaba el carrito se puede comentar y reemplazar por una propiedad computada llamada total. La idea: usar una reducción para sumar los montos de los ítems.
Crear total como variable computada y retornarla.
O definir total directamente dentro de reactive del carrito.
Mantener el cálculo declarativo y derivado de sus dependencias.
Como variable independiente:
import{ computed }from'vue'const total =computed(()=>// sumar el monto de cada ítem del carrito cartState.cart.reduce((acc, item)=> acc +/* valor del ítem */,0))return{ total }
Dentro del estado del carrito:
import{ reactive, computed }from'vue'const cartState =reactive({cart:[],total:computed(()=> cartState.cart.reduce((acc, item)=> acc +/* valor del ítem */,0)),})// no es necesario retornar total por separado
Palabras clave y habilidades aplicadas:
Composition API y Options API: enfoques para organizar la reactividad.
computed: derivar valores a partir de dependencias reactivas.
reactive: agrupar estado y propiedades computadas en un mismo objeto.
watcher: evitado cuando la lógica puede escribirse como propiedad computada.
Dependencias reactivas: disparan el recálculo automático.
Operador ternario: simplifica condiciones como stock bajo/alto.
reduce: cálculo del total del carrito de forma declarativa.
¿Te gustaría ver ejemplos con más condiciones, como descuentos en el total o colores por rangos de stock? Deja tu comentario y cuéntame qué casos prácticos quieres resolver.
Desde que inicio el curso tenía la duda de cómo recargaba borrando cache jaja ya encontré cómo, les dejo el fragmento:
"La combinación de teclas para esto es Ctrl + Shift + R o Shift + F5 en Google Chrome y Ctrl + F5 en Mozill Firefox, aunque en el primer navegador web también se puede acceder desde el modo desarrollador, haciendo clic derecho en el botón de recargar."
Puedes utilizar la extensión de live server para ahorrarte el paso de recargar. Saludos
estoy acostumbrado a trabajar con el método de las options API . por que así lo aprendí en vue 2 .
y en mis trabajos seguiría usando ese método , Me siento más como. Aunque siempre es bueno conocer Composition API .
Hacen todo más sencillo, estaba algo confundido con los watches porque era algo largo pero ya con los computed me queda más claro
Para utilizar propiedades computadas, se debe importar el objeto computed de Vue, en composition API. Es importante recordar que todas las propiedades y funciones, se deben retornar dentro del setup
Porque me sale este error??
"Write operation failed: computed value is readonly"
Ayudaaa!!
const{ createApp, ref, reactive, toRefs, watch, computed }=Vue;const app =createApp({setup(){const products =ref([{name:"Camara",price:450_000,stock:3,content:`Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt
atque dolorum corporis, reiciendis eaque temporibus quod magnam amet
ea natus delectus? Aut placeat ipsam minus labore voluptas. Porro,
vel aliquid!`,images:[{image:"./img/camara.jpg",thumbnail:"./img/camara-thumb.jpg"},{image:"./img/camara-2.jpg",thumbnail:"./img/camara-2-thumb.jpg"}],offer:true,new:true,quantity:1},{name:"Microfono",price:950_000,stock:3,content:`Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt
atque dolorum corporis, reiciendis eaque temporibus quod magnam amet
ea natus delectus? Aut placeat ipsam minus labore voluptas. Porro,
vel aliquid!`,images:[{image:"./img/camara.jpg",thumbnail:"./img/camara-thumb.jpg"},{image:"./img/camara-2.jpg",thumbnail:"./img/camara-2-thumb.jpg"}],offer:true,new:true,quantity:1},{name:"Camara PL",price:250_000,stock:2,content:`Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt
atque dolorum corporis, reiciendis eaque temporibus quod magnam amet
ea natus delectus? Aut placeat ipsam minus labore voluptas. Porro,
vel aliquid!`,images:[{image:"./img/camara.jpg",thumbnail:"./img/camara-thumb.jpg"},{image:"./img/camara-2.jpg",thumbnail:"./img/camara-2-thumb.jpg"}],offer:true,new:true,quantity:1},{name:"Audifonos PL",price:750_000,stock:5,content:`Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt
atque dolorum corporis, reiciendis eaque temporibus quod magnam amet
ea natus delectus? Aut placeat ipsam minus labore voluptas. Porro,
vel aliquid!`,images:[{image:"./img/camara.jpg",thumbnail:"./img/camara-thumb.jpg"},{image:"./img/camara-2.jpg",thumbnail:"./img/camara-2-thumb.jpg"}],offer:true,new:true,quantity:1}]);const cartState =reactive({cartOpen:false,cart:[],total:computed(()=>{return cartState.total= cartState.cart.reduce((prev, curr)=>{const prevPrice = prev.price|| prev;const prevQuantity = prev.quantity||1;return prevPrice * prevQuantity + curr.price* curr.quantity;},0);})/* total: 0 */});/* const total = computed(()=>{
return cartState.total = cartState.cart.reduce((prev, curr) => {
const prevPrice = prev.price || prev;
const prevQuantity = prev.quantity || 1;
return prevPrice * prevQuantity + curr.price * curr.quantity;
}, 0);
}) */functionaddToCart(product){const prodIndex = cartState.cart.findIndex(prod=> prod.name=== product.name);if(prodIndex >=0){ cartState.cart[prodIndex].quantity+=1;}else{ cartState.cart.push(product);} product.stock-=1;}/* watch(cartState.cart, (value, oldValue) => {
cartState.total = cartState.cart.reduce((prev, curr) => {
const prevPrice = prev.price || prev;
const prevQuantity = prev.quantity || 1;
return prevPrice * prevQuantity + curr.price * curr.quantity;
}, 0);
}) */return{...toRefs(cartState), addToCart,
products
};}});
El código lo veo igual al del profesor, seria mirar el código donde se esta renderizando la propiedad computed
Me hubiera gustado que el proyecto tenga mas estilos, y este mas bonito. Aunque se que esta fuera del alcance del curso. Con un poquito de CSS mejora un monton. Porque? porque este proyecto se puede presentar en una entrevista u otra persona, y asi como esta no lo podria presentar... tocara arreglarlo un poco "bastante" diria yo.
Me parecio curioso que dentro del segundo computed, estamos llamando a cartState dentro del mismo
Las ventajas de usar un objeto reactivo, Crear propiedades computadas dentro de ese objeto! WoW
Es mejor idea pensar en una propiedad computada siempre que necesitemos calcular un valor en función a otras propiedades, teniendo en cuenta que Vue volverá a evaluar la propiedad cada vez que alguna de sus dependencias cambie y no necesitaremos un watch personalizado por cada dependencia. Pero un watch sería mejor si en cambio necesitamos realizar algo más complejo como llamadas http, configurar un timer o guardar datos en el local storage.
Las propiedad computadas son propiedades que se calculan a partir de otras