Guillermo Castaño Vèlez
Manuel Sebastián
Luis Cano
Carlos Rodríguez
Eduardo Razo Cobián
Andrés Felipe Perdomo Alvarado
Jose Flores
Lev Merino
Jose Morales Varon
John Ortiz
Juan Guillermo Perez Cardozo
Miguel Angel Reyes Moreno
Alexis Allamano
Kenneth Angulo L
Brayhan Andres Jaramillo Castaño
Diana Martinez
Brayhan Andres Jaramillo Castaño
Ali Guevara
Diana Martinez
Jesus Antonio Castaneda Valencia
Diana Martinez
Jose Lopez
Diana Martinez
fabio andres zamora osorio
Diana Martinez
Mario Israel Ruiz Díaz
Juan Becerra
Sergio Fernandez
JOSE MANUEL MONTAÑO SAENZ
Ariel González Falcón
En el curso profesional de VUE, el viejo, hay una clase que se llama el event bus... es muy interesante. Hay forma de emitir eventos a componentes que no estan relacionados directamente.... hermanos, abuelos.. etc. Con props y emits tocaría hacer toda una culebra de props y eventos. Con esta clase que les digo aprendemos una forma genial para que esto no pase. Lo he provado en VUE 2.x, no el 3.x
Buen dato!
En vue 3 recomiendan no usar event bus para manejar el global state, es mucho mejor usar vuex (pinia) o las librerias del link: Event Bus
Lo que pasó con el método que no funcionaba la reactividad es que Vue envuelve los métodos de mutación de una matriz observada para que también activen las actualizaciones de vista. . Los métodos envueltos son: push(), pop(), shift(), unshift(), splice(), sort(), reverse(). Si uso filter() entonces debo volver a asignarlo ya que filter no es mutable, así como lo hizo la profesora:
this.numbers = this.numbers.filter((el, index) => index !== i);
O así:
const items = this.numbers.filter((el, index) => index !== i); this.numbers = items;
Sí quieres algo más sencillo es recomendable usar los métodos que sugiere Vue:
remove(i) { this.numbers.splice(i, 1); }
en realidad solo era un error en la variable, uso "this.item" cuando debió haber sido "this.items"
methods: { remove(item){ this.items = this.items.filter((el, index) => index !== item); } },
En el componente hijo también se puede ejecutar el emit directamente en el evento, para evitar crear la función rm:
template: ` <li @click="$emit('remove')"> {{ text }} </li>`
Resumen
Para comunicar que paso dentro del componente hijo al padre, se lo hace saber mediante el disparo de eventos, los cuales son personalizados por nosotros
// Dentro del componente padre <v-component v-on:eventoProvenienteHijo="metodo">
// Dentro del componente hijo <button v-on:click="metodoQueDIsparaEvento"> Delete </button> // Methods del hijo metodoQueDisparaEvento () { this.$emit("eventoProvenienteDelHijo", dataOpcional) }
No encontraba la manera de poder emitir un método desde un componente hijo en la clase anterior para eliminar los posts, pero con esto se me facilito mucho. Buenísimo curso
En estos cursos recientes sería bastante bueno que al final se aplicara lo aprendido construyendo un proyecto. Me parece bastante completo, así como se venía haciendo en los cursos antiguos de Vue.js
Hola.
Algunos sitios los he desarrollado con jQuery porque me parece que tiene una sintaxis concisa y poderosa para manejar el DOM de un documento HTML pero al obserfar la funcionalidad que ofrece este framework progresivo me impresiona la facilidad con la que se pueden hacer manipulaciones del DOM.
Y es que también es cierto que basta con incorporar la librería con la etiqueta script para empezar a crear aplicaciones sencillas que requieran no sólo gestionar los datos sino los eventos del usuario. ¡Genial!
Saludo,
uy profe es muy facil entenderle, explica 12/10
Yo quise que en una lista de números, el número al que le hagas click se convierta en su valor cuadrado:
const app = Vue.createApp({ el: '#app', data() { return { items: [ 1,2,3,4,5,6,7,8,9,10 ] } }, template: ` <ul> <v-item v-for="item, index in items" v-bind:number="item" v-on:click="square(item)" :key="index" > {{ item }} </v-item> </ul> `, methods: { square(i) { console.log(i) this.items[i-1] = i * i } }, }) app.component('v-item', { props: { number: Number }, template: `<li>{{ number }}</li>` }) const vm = app.mount('#app')
Cómo no poder decirle que no se eliminó el elemento 2 solo porque puso
this.item = ...
En lugar de
this.itemS
Esta parte estuvo un poco comleja pero se entiende el concepto.
Padre:
<h3>Clase 18: Comunicación hijo a padre con eventos personalizados</h3>
\
<Emisor v-on:saludo="recibirSaludo" />
<p>Mensaje recibido por el padre: {{ mensajeRecibido }}</p>
Hijo:
<script setup>
const emit = defineEmits(['saludo']);
function enviarSaludo() {
emit('saludo', 'Hola desde el componente hijo');
}
</script>
<template>
<button v-on:click="enviarSaludo">Enviar saludo al padre</button>
</template>
Si hago lo siguiente.
this.$emit("remove", 200);
Como puedo obtener ese 200?
Cuándo consumes tu componente agregas el handler, por ejemplo:
// Al definir el componente: this.$emit("remove", 200); // Al usar el componente <Component @remove="onRemove" /> // Al definir el handler methods: { onRemove(id) { console.log("id:", id); } // Salida esperada >> id: 200 },
Si ese onRemove ya esta recibiendo un parametro, ya no funcionaria. En la clase se esta pasando un key como parametro (i)
hay alguna forma de que el componente hijo sepa cuando termina la ejecución del metodo dentro del evento creado con emit ?
Directamente no, delega esa responsabilidad al receptor, quien puede emitir alguna señal en respuesta, como modificar un prop.
En la función remove() a que hace referencia la variable “el”
this.items = this.items.filter((el, index)) => index !== i);
Al elemento de la lista, lo que estámos haciendo es un filtro que recorre todos los elementos de la lista, y los devuelve, excepto si el index que queremos remover es igual al index de un item, en ese caso no lo devuelve, y así eliminamos ese item de la nueva lista, que se asigna inmediatamente a la variable this.items.
Una pregunta... en Reactjs yo puedo crear componentes y guardarlos en carpetas de diferentes directorios para acceder de una manera mas ordenada al codigo, de esta manera separo los componentes padres o hijos, se puede hacer algo parecido en Vuejs ?
Claro, hacerlo dentro de la carpeta components es un estándar no escrito, pero puedes hacerlo como quieras, solo necesitarás configurar el entorno para que los encuentre y listo, aunque la verdad te recomendaría usar esa carpeta, ya que muchos plugins y cosas que a veces agregamos adicional a nuestros proyectos, asumen esa estructura, eso si, dentro de la carpeta components puedes crear la estructura de carpetas que se te antoje.
A continuacion voy a dar el contexto de la duda que tengo y al final pongo la pregunta.
.
En el codigo de esta clase en el componente padre donde se pone:
.
v-for="(item, i) in items"
v-bind:text="item"
v-on:delete="remove(i)"
.
esa llamada del metodo remove(i) asignado al v-on ya esta recibiendo el parametro i por lo que no puede recibir otros parametros enviados desde el $emit() del componente hijo, osea, si en el componente hijo se pone
.
this.$emit("delete", 10, "adios")
.
entonces los datos 10 y "adios" no se envian a la llamada del metodo remove(i) asignado al v-on del componente padre ya que dicho metodo ya esta recibiendo el parametro i. Aunque se coloque v-on:delete="remove(i, a, b)" donde a y b serian los parametros enviados desde el emit() del componente hijo igual dichos parametros no son enviados al metodo remove(i, a, b).
.
Me di cuenta de esto porque si la llamada del metodo remove(i) se deja sin parametros, osea si se le quita el parametro i poniendo solo v-on:delete="remove" entonces ahora si esa llamada del metodo remove recibe los parametros enviados desde el metodo emit() del componente hijo, osea ahora poner en el componente hijo this.$emit("delete", 10, "adios") hace que en el componente padre la llamada del metodo remove si reciba los parametros 10 y "adios"
.
Mi pregunta es ¿Como puedo hacer para que la llamada del metodo remove(i) del componente padre aunque ya este recibiendo el parametro i pueda recibir los parametros enviados desde el emit() del componente hijo?
Para resolverlo, vue agrega la variable $event, puedes recibirla desde donde recibes el evento, y pasarlo como argumento a la función, así:
v-on:delete="remove(i, $event)"
De ese modo le estás pasando la i y el evento. Otro detalle, $emit solo puede recibir dos argumentos, el evento y el valor, $emit("delete", 10), si agregas otro argumento, no podrás recuperarlo con $event, por eso en lugar de pasar el valor, puedes pasar un JSON, así $emit("delete", { id: 10, text: "adios" }).
Si quieres mandar un valor del componente al createApp, a través de un método declarado en el padre, lo puedes hacer así (ver método agregar y componente v-but):
const app = Vue.createApp({ data(){ return { items:['uno','dos','tres'] }; },methods:{ eliminar(i){ this.items = this.items.filter((el,index)=> index !==i ); }, agregar(data){ this.items.push(data); } }, template: ` <ul> <v-li v-for="(item,index) in items" :key="index" v-bind:text="item" @eliminar="eliminar(index)" /> </ul> <v-but @agregar="agregar" /> ` }); app.component('v-li',{ props: { text: String }, methods:{ rm(){ return this.$emit("eliminar"); } }, template: `<li @click="rm" >{{text}}</li>` }); app.component('v-but',{ data(){ return{ dato: "" }; }, props: { text: String }, methods:{ rm(){ return this.$emit("eliminar"); }, ad(){ return this.$emit("agregar",this.dato); } }, template: `<input type="text" v-model="dato" /> <button @click="ad"> agregar </button> ` });
Hice el ejemplo con un array de emojis y hice que el componente hijo le dijiera al componente padre que emoji fue eliminado:
<script> const app = Vue.createApp({ data() { return { emojis: ["😀", "👋", "😻", "🍕", "😎", "🐱💻"], emojiDeleted: "", }; }, methods: { removeEmoji(vFromChild, index) { this.emojis = this.emojis.filter((emoji, i) => { return i !== index; }); console.log(`Se ha eliminado el emoji ${vFromChild}`); this.emojiDeleted = vFromChild; }, }, template: ` <div> <ul> <v-item v-for="(emoji, index) in emojis" :key="emoji" :emoji="emoji" @remove="removeEmoji($event, index)" /> </ul> <div v-if="emojiDeleted.length > 0"> <p>This emoji has been deleted: {{ emojiDeleted }}</p> </div> </div> `, }); app.component("v-item", { props: { emoji: { type: String, default: "caballo", }, }, emits: ["remove"], methods: { rm() { this.$emit("remove", this.emoji); }, }, template: ` <li @click="rm" style="cursor: pointer">{{ emoji }}</li> `, }); const vm = app.mount("#app"); </script>
¿Cómo funciona this.$emit?
$emit es un metodo de Vue que permite indicarle en este caso al método "remove" que este atento al evento click que se esta generando desde el componente hijo y que se ejecute al accionarse el click.
en el minuto 6, el error donde no se actualizaba la lista cuando se activaba el evento de click, lo pude resolver de una manera mas sencilla que reasignando manualmente las variables. Solamente hice un return directamente del .filter
remove(i){ return this.items = this.items.filter((el, index)=> index !== i) }