Aprende a pasar datos de forma clara y escalable en Vue. Aquí verás cómo estructurar componentes, mantener el flujo unidireccional de información y usar props para conectar un padre con sus hijos tanto en Composition API como en Options API. Ideal para reutilizar estado, reducir errores y mantener el código limpio.
¿Por qué el flujo va de padre a hijo y qué rol cumplen las props?
Vue organiza la interfaz en una jerarquía: la app es el padre y cada componente es hijo. Según su filosofía, el flujo de información es de una sola dirección: de padre a hijo. Para lograrlo, se utilizan props: propiedades definidas en el hijo a las que el padre les pasa valores.
Flujo unidireccional: evita inconsistencias y hace el estado predecible.
Componentes anidados: un hijo puede tener sus propios hijos.
Props: el hijo declara qué espera recibir; el padre envía con v-bind.
Listas y repetición: el padre puede renderizar múltiples hijos con v-for y una key única.
En este enfoque, el estado “vive” donde debe vivir: datos globales o compartidos en el padre; datos específicos en el hijo cuando procede.
¿Cómo implementarlo en Composition API?
Primero se aisló el estado del producto dentro de un componente usando setup y un estado reactivo. Luego se detectó que la función add to cart dependía del estado definido en el padre. La solución fue mover el arreglo de productos al padre y pasar cada producto al hijo mediante una prop.
¿Cómo define el padre la lista y pasa el producto?
Define una referencia de productos: un arreglo con varios objetos producto.
Recorre la lista y crea una instancia del componente por elemento.
Usa v-bind para pasar el producto actual y una key única basada en el nombre.
<!-- Padre (template) --><Productv-for="product in products":key="product.name":product="product"/>
// Padre (script) — Composition APIimport{ ref }from'vue'const products =ref([{name:'P1',price:10,stock:3},{name:'P2',price:20,stock:5},{name:'P3',price:15,stock:2},])
¿Cómo declara el hijo la prop y la usa en setup?
El componente hijo declara la prop en su definición: props: ['product'].
En setup(props) se accede a props.product para leer datos del producto.
Se exponen métodos como add to cart y apply discount desde setup.
// Hijo (Product.js) — Composition APIexportdefault{props:['product'],setup(props){functionaddToCart(){// usa props.product.}functionapplyDiscount(){// lógica de descuento.}return{ addToCart, applyDiscount,product: props.product}},template:` <div>
<h3>{{ product.name }}</h3>
<p>Precio: {{ product.price }}</p>
<p>Stock: {{ product.stock }}</p>
<button @click="addToCart">Agregar al carrito</button>
</div>
`,}
Puntos clave aprendidos:
Declarar props en el hijo para permitir que el padre envíe datos.
Recibir props en setup(props) para acceder a props.product.
Reutilización: el mismo componente se instancia por cada elemento en la lista.
Manejo de estado: el arreglo de products vive en el padre; el hijo consume y actúa.
¿Cómo se logra lo mismo con Options API?
El patrón es muy similar. Se define props: ['product'] en el componente y se accede desde el contexto con this.product. El padre recorre la lista y pasa la prop igual que en Composition API.
¿Cómo se declaran props y se accede con this?
En el hijo, props: ['product'] agrega product al contexto.
En el template se puede leer product directamente, o como this.product en métodos.
// Hijo — Options APIexportdefault{props:['product'],methods:{addToCart(){// usa this.product.},applyDiscount(){// lógica de descuento.},},}
<!-- Padre — Options API --><Productv-for="product in products":key="product.name":product="product"/>
Beneficios prácticos:
Consistencia entre Composition API y Options API al definir props.
Contexto claro: en Options API, this.product es la prop inyectada; en Composition API, props.product en setup.
Escalabilidad: separar el estado global (padre) del estado específico (hijo) evita errores como en add to cart cuando el dato no está donde se espera.
¿Tienes dudas sobre cómo organizar tu estado o cómo estructurar tus props? Comenta tu caso y vemos cómo optimizarlo.
Si, estuve intentando ordenar el código y tuve varios errores que tardé en solucionar
Esta es la forma en la que los padres se comunican con los hijos dentro de Vue, para el caso de Composition, si siguieron la recomendación de destructurar el prodState, en este caso simplemente hay que sustituir la destructuración del prodState por la destructuración de props.
.
Básicamente, todo lo que esté dentro del props que definimos en los componentes son todos los datos que le está mandando el componente padre al componente hijo. por eso es que "recibimos" la propiedad del componente padre en props.
.
Una forma un poco más elegante de escribir los atributos de props es hacerlo mediante un objeto JSON que especifica ciertas características de un atributo que se va a recibir, por ejemplo:
En este caso, hacemos que el dato que queramos recibir desde el padre tiene que cumplir unas ciertas reglas (de lo contrario arrojará error), por ejemplo, debe ser requerido que el padre le mande el producto a dicho componente, debe ser de tipo Object, por defecto podemos poner un objeto vacio (en caso en que required sea false), e incluso podemos meter una validación de los datos que mande el padre.
.
Son pequeñas cositas que Vue permite hacer, dejo el código de esta clase:
.
https://github.com/RetaxMaster/vue3-platzi-commerce/tree/d2bc632704c097018a03675de04b75be0664bc35
En el minuto 7:46 no está funcionando lo que hace, está repitiendo el contenido estático (CAMARA) del archivo product.js, no de la lista products del archivo index. En la pestaña superior del archivo product.js se ve que el archivo fue modificado pero no lo guardó, entonces el sistema sigue tomando la version vieja. Si lo tomamos tal cual como está da un error, el código tal como está debería fallar, solo que tiene dos fallas juntas y una falla oculta a la otra. Porque el elemento product del archivo js realmente está vacío y el nombre de los productos del index.html no coincide con lo que se muestra en el navegador
También se podría des-estructurar:
setup({ producto }){....}
mucho mejor
Aunque suene muy atractivo usar ese modo Vue te dice lo siguiente:
WARNING
However, because props are reactive, you cannot use ES6 destructuring because it will remove props reactivity.
entonces props ¿sirve para pasar del padre al hijo datos?
si, en este casi si, solo para pasar datos de el padre al hijo pero del hijo al padre ya se usan eventos
Definitivamente me gusta mucho más OptionAPI que CompositionAPI, sobre todo cuando modulamos el option y con eso tenemos las ventajas del composition
jajajaj la idea es aprender en composition jajaja no te cierres al cambio mi hermano jajaja xD
Como no entendo muy bien lo de reactive, me quedo tronando porque se borra el productState.
En el setup estoy enviando setup(props) y la usamos tal cual props.product, pero que pasa si las props son mas de 1 valor ?, seria props.valor ?
¿Es una mala practica pasar las funciones dentro del setup del componente?
A alguien le sale este error?
SyntaxError: Unexpected identifier 'Intl'. Expected a ':' following the property name 'new'.
En:
${{ new Intl.NumberFormat("es-CO").format(product.price) }}
El código tiene un error
Sí, el código tiene un error. El error se encuentra en la línea de código donde se ligan las variables a los elementos HTML. Los elementos aún no existen en ese momento, por lo que las variables se les asigna el valor de 'null'. La solución es mover esa línea de código después de que los elementos se hayan inyectado en el HTML.
veo que el profesor hace referencia a composition API y esta usando data() y this, por la documentación eso es option API. ref, reactive, y computed son de composition... se me armo un kilombo en la cabeza o no se si toy mal.... pero ando mas perdido
Hola, siento que cuando muestran una opción junto a otra, es más pesado de aprender. Creo que si se aprende una en un curso y luego la otra forma en otro sería más fácil de comprender. Siento que cuando son conocimientos nuevos, hace más daño que bien, combinarlos, es mi punto de vista.
Si ya saben vue2, intenten hacer todo el ejercicio en options, y despues haganlo en composition, es una muy buena practica.
En mi caso me quede como 10 minutos leyendo el codigo para entender que no habia retornado los products y por eso me salia la pantalla vacia jajaja xD
Podemos utilizar las herramientas de búsqueda (ctrl + f) o remplazo (ctrl + h)de Visual Studio Code para cambiar las variables en vez de buscar linea por linea.
Hola gente, como se importa si decido tener mi archivo principal js aparte y tambien pongo mi componente en otro js. ¿Cómo se importaria?
Usaría export pero, ¿A qué? ¿A product?
Entiendo que en el html seria con "<script src="app.js"></script>"
Pero entonces en esa etiqueta usaria el atributo type con valor "module"?
Gracias por tu respuesta sin embargo notó que esa solución es en Vue 2.x y no en la version 3.x. Además, están utilizando archivos con extensión ".vue" a diferencia nuestra que usamos extension ".js". Tambien lo que me causa ruido es que el mentor junta html y JS por lo que usando extension JS, como extenderiamos un segundo componente con extension js a otro archivo JS. No se si usariamos modulos de ES6 o export propio de node.js
Saludos.
Estoy teniendo el error cartState is not defined. ¿Qué puede ser?
Puedes mostrarnos tu codigo?
Al final sí pude solucionarlo, estaba confundiendo la sintaxis del composition con la de options