Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Comunicación entre Componentes: propiedades

17/38
Recursos

Aportes 45

Preguntas 12

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

🐪 camelCase
🧮 PascalCase
🐍 snake_case
🍢 kebab-case

En props definimos las propiedades que el componente padre le va a enviar al hijo. Los props se utilizan igual que las propiedades de data, se utilizan a través de this. El componente hijo no puede escribir o modificar los props que le mande el padre.
.
El nombre del componente se escribe en Pascal Case, donde cada palabra inicia con la primera letra en mayúscula. Al momento de llamar al componente en el HTML, Vue parsea el nombre a Kebab Case, una nomenclatura con guiones lo cual permite mantener una consistencia con los tags HTML.
.
Se recomienda mantener la consistencia entre los lenguajes, utilizar Pascal Case dentro de JavaScript: CoinDetail ; y Kebab Case dentro de HTML: coin-detail.
.
Para pasarle las propiedades al componente se hace desde el HTML usando la directiva v-bind: v-bind:change-percent = “changePercent”. Aquí también aplica lo del Kebab Case.
.
Los componentes de Vue necesitan tener un componente padre único que encierre a todos los demás.
.
Cuando las propiedades tienen un elemento central común es más cómodo trabajarlas mediantes un objeto, así evitamos tener que estar pasando tantos props.

Voy a tener que ver varias veces esta clase, por un lado está muy interesante y por el otro para que quede todo claro.

Complementando lo mencionado al respecto sobre las propiedades. Las propiedades, pueden ser listadas como un objeto donde se refleja los nombres y valores/tipos:

props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // or any other constructor
}

me hizo sudar esta clase, pero estuvo genial generar una sola moneda como objeto

Qué otra opción hay para tener templates de HTML fuera del JS? No me parece muy cómodo escribirlo directamente allí.

codigo

Vue.component('CoinDetail',{
    props:['coin'],
    data(){
        return{
            showPrices:false,
            value:0
        }
    },
    computed:{
        title(){
            return `${this.coin.name} + ${this.coin.symbol}`;
        },
        convertedValue(){
            if(!this.value){
                return 0;
            }
            return this.value / this.coin.price
        }
    },
    methods:{
        toggleShowPrices(){
            this.showPrices =!this.showPrices
        }
    },
    template: `
    <div>
        <img 
            :src="coin.img" alt="" 
            @mouseover="toggleShowPrices"
            @mouseout="toggleShowPrices"
        >
        <h1 :class="coin.changePercent > 0 ? 'green' : 'red' ">
            {{title}}
            <span v-if="coin.changePercent > 0">👍</span>
            <span v-else-if="coin.changePercent < 0">👎</span>
            <span v-else>🤞</span>
            <span @click="toggleShowPrices">
                {{showPrices ? '🙈' : '🐵'}}
            </span>
            <input type="number" v-model="value">
            <span>{{convertedValue}}</span>
            <ul v-show="showPrices">
                <li
                class="uppercase"
                :class="{orange: item.value == coin.price, red: item.value < coin.price, green: item.value > coin.price }"
                v-for="(item, index) in coin.pricesWithDays"
                :key="item.day">
                    {{index}} - {{item.day}} - {{item.value}}
                </li>
            </ul>
        </h1>
    </div>
    `
});

new Vue({
    el:'#app',
    data() {
        return {
            btc:{
                name:'Bitcoin',
                symbol:'BTC',
                img:'https://cryptologos.cc/logos/bitcoin-btc-logo.png',
                changePercent:-10,
                price:8400,
                pricesWithDays: [
                    { day: 'Lunes', value: 8400 },
                    { day: 'Martes', value: 7900 },
                    { day: 'Miercoles', value: 8200 },
                    { day: 'Jueves', value: 9000 },
                    { day: 'Viernes', value: 9400 },
                    { day: 'Sabado', value: 10000 },
                    { day: 'Domingo', value: 10200 },
                ],
            },
            
            color: 'f4f4f4'
        }
    },/*
    methods: {
        toggleShowPrices(){
            this.showPrices = !this.showPrices;
            this.color =this.color.split('')
            .reverse().join('');
        }
    },
    */
})

Hasta ahora esta ha sido la clase más difícil 😂

  • Componente hijos no puede modificar las propiedades enviadas por el padre.
  • Es necesario usar v-bind para pasar propiedades dinámicas de lo contrario se pasara el string literal.
  • Si se definen las propiedades en el componente en camelCase se podrán citar en el padra así msimo o en formate de guiones bajos.

Cuando nosotros definimos un componente, data debiera ser un función. Y la razón de ello es por el concepto de encapsulamiento, permitiendo que cada instancia pueda mantener una copia independiente del valor retornado.

Por ejemplo, si tuviéramos :

data: {
  count: 0
}

Y definiendo nuestros componentes de la siguiente manera:

<div id="components-demo">
  <button-counter></button-counter>
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>

Tendríamos un efecto donde todos nuestro componentes, reciclan código y, además, una misma declaración de data. Por ello, se define a data:

data: function () {
  return {
    count: 0
  }
}
# o también
data () {
  return {
    count: 0
  }
}

tengo una duda, yo escribí el codigo del componente despues de la instancia de VUE, es decir despues de New vue, etc, pero no me funcionaba correctamente, por lo que deje como lo escribe el profe, pero no entiendo por que sucede esto si en teoria estoy creando primero la instancia padre de vue y luegos sus omponentes, o son cosas diferentes ?

Que tan correcto o valido es tener varias instancias de Vue " const app = new Vue({…}) " podria generar bugs? se considera una mala practica?
Gracias.

¿existe repositorio de este curso?

Las propiedades props se usan de la misma forma que las propiedades data, la única diferencia es que no pueden ser modificadas por el componente hijo.

¿Qué ocurriría si no paso alguna de las propiedades del padre al hijo? ¿Hay forma de definir un valor por defecto?

Si el valor showPrices, esta agregado en el padre, porque se redefine showPrices en la seccion de webcomponent?

f

¿Puedo crear un componente dentro de otro componente?

Por lo que veo hay que tener buen ojo al definir responsabilidades de componentes padres e hijos. Debería buscar documentación al respecto.

Excelente clase, me perdí un poco al ir copiando y pegando código pero al final el código sí queda mucho más entendible y claro para su lectura.

Podemos enviar propiedades a un componente desde el objeto methods ? Me explico…

Me gustaría mostrar un modal con una información que le llega por propiedades, pero la información está dentro de un v-for y si meto ese componente modal **dentro del v-for **sería fácil simplemente pasarle las props pero entonces se crearía 10,20,30 instancias de ese componente modal.

Me gustaría enviar un evento con @click (desde el v-for), interceptarlo en el objeto methods de la instancia de Vue y luego enviarle (de alguna manera) las propiedades al componente modal que está fuera del v-for.

Espero haberme explicado…Gracias !!

El profesor explica de maravilla, solo a veces me cuesta un poco seguir el ritmo por más bien que expliquen, es cosa mía, si alguien tiene esa situación igual que yo, les recomiendo poner el video en velocidad 0.85x y les quedará perfecto!

Muy buena clase 😃

💯

Comunicación entre Componentes: propiedades

En el componente de Vue podemos poner como nombre ‘coinDetail’ y en el HTML usar el nombre ‘coin-detail’.

El nombre de ‘coin’ dentro de props viene del componente padre, en el objeto ‘btc’.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Primera Vue</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div
    id="app"
    v-bind:style="{ background: '#' + color }">

    <coin-detail
      v-bind:coin="btc"
    >
    </coin-detail>

  </div>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
  <script src="app.js"></script>
</body>
</html>
Vue.component('coinDetail', {
  props: ['coin'], //*Pertenecen al componente 'padre'
  data() {
    return {
      showPrices: false,
      value: 0,
    }
  },
  methods: {
    toggleShowPrices() {
      this.showPrices = !this.showPrices
    }
  },
  computed: {
    title () {
      return `${this.coin.name} - ${this.coin.symbol}`
    },

    convertedValue () {
      if(!this.value){
        return 0
      }
      return this.value / this.coin.price
    }
  },
  template: `
    <div>
      <img
        v-on:mouseover="toggleShowPrices"
        v-on:mouseout="toggleShowPrices"
        v-bind:src="coin.img"
        v-bind:alt="coin.name"
      >

      <h1
        v-bind:class="coin.changePercent > 0 ? 'green' : 'red'">
        {{ title }}
        <span v-if="coin.changePercent > 0">🤑</span>
        <span v-else>🤯</span>
        <button v-on:click="toggleShowPrices">
          {{ showPrices? '🙈' : '🐵' }}
        </button>
      </h1>

      <input type="number" v-model="value">
      <span>{{ convertedValue }}</span>

      <ul v-show="showPrices">
        <li
          class="uppercase"
          v-bind:class="{
            green: p.value > coin.price,
            orange: p.value === coin.price,
            red: p.value < coin.price,
          }"
          v-for="(p, index) in coin.pricesWithDays"
          v-bind:key="p.day">
          {{ index }} - {{ p.day }} - {{ p.value }}
        </li>
      </ul>
    </div>
  `
})

new Vue({
  el: '#app',

  data() {
    return {
      btc: {
        name: 'Bitcoin',
        symbol: 'BTC',
        img: 'https://cryptologos.cc/logos/bitcoin-btc-logo.png',
        changePercent: 10,
        price: 8400,
        pricesWithDays: [
          { day: 'Lunes', value: 8400 },
          { day: 'Martes', value: 7900 },
          { day: 'Miercoles', value: 8200 },
          { day: 'Jueves', value: 9000 },
          { day: 'Viernes', value: 9400 },
          { day: 'Sabado', value: 10000 },
          { day: 'Domingo', value: 10200 },
        ],
      },
      color: 'f4f4f4',
    }
  },

  /* methods: {
    toggleShowPrices() {
      this.showPrices = !this.showPrices;

      this.color = this.color.split('').reverse().join('');
    }
  } */
});

buen curso, solo falta subir los archivos

Comunicación entre Componentes

Cuando se requiere enviar una propiedad de un componente padre a un componente hijo; al trabajar con Vue el componente padre de una aplicación es la instancia app que definimos, pero a final de cuentas no deja de ser un componente, ésta tiene prácticamente las mismas propiedades que los componentes hijos.

Como la propiedad que queremos que llegue del padre al hijo ya se encuentra en la propiedad data de la instancia de Vue es necesario utilizar la propiedad props de los componentes, donde se puede definir que propiedades del componente padre que le enviará al componente hijo.

props: ['changePercent'],

Por ej. Se definió una propiedad llamada changePercent, indicando que el componente padre le va a setear a través de changePercent el valor del componente padre al componente hijo.

Se debe de tener en cuenta que las propiedades tienen prácticamente la misma funcionalidad que las propiedades dentro de data, se utilizan de la misma forma a través de this, dentro de las expresiones, dentro de las directivas. La única diferencia es que las propiedades que vienen mediante props, pertenecen al componente padre, por lo tanto, el componente hijo no puede escribir o remplazar el valor de éstas propiedades.

Vue convierte la nomenclatura PascalCase(Como se declara en los archivos JS, por ej: CoinDetail) automáticamente parsea a la nomenclatura Kebab-case(Nomenclatura con guiones, manteniendo una consistencia en los tags HTML). Si en el HTML quisiéramos escribir PascalCase podríamos hacerlo.

🐪 camelCase
🧮 PascalCase
🐍 snake_case
🍢 kebab-case

<coin-detail></coin-detail>

ó

<CoinDetail></CoinDetail>

Para pasar en el HTML las propiedades al componente es utilizando el mismo patrón que utiliza HTML, mediante los atributos. Para que las propiedades tengan valores dinámicos es necesario que las propiedades tengan la directiva v-bind. Con ello el componente tendrá el valor real de la propiedad computada y no el valor literal de la palabra title.

<coin-detail 
      v-bind:title="title"
      v-bind:changePercent="changePercent"
></coin-detail>

Vue parsea las propiedades de manera similar a como parsea los componentes, en el JS la propiedad changePercent se está definiendo con camelCase, pero dentro del HTML también es posible utilizarla con Kebab-case change-percent y así mantener la consistencia de lo que hace el lenguaje.

Es importante recordar que los elementos o componentes de Vue deben tener un componente padre único.

En lugar de recibir todo un set de props en el componente hijo, es posible recibir una sola propiedad el cuál establece el comportamiento de una determinada configuración, todas las propiedades que se habían utilizado se convertirán en hijas de la propiedad única o padre.

Las propiedades internas del componente hijo no son compartidas ni accesibles al componente padre. El componente padre le envía las propiedades que quiere al componente hijo y el componente hijo utiliza esta información para mostrarlo en pantalla.

Perfecto! En conclusión, ya que las props que recibía el componente hijo eran muchas, simplemente las metió en un objeto “btc” y se lo envió a los props del hijo.

Excelente clase!

pasar al componente un objeto con todas las propiedades nos ayuda a tener un codigo mas limpio y facil de trabajar a tener q incluir todas las propiedades separadas y una lista larga de directivas v-bind:

Este código del componente se puede dividir en archivos separados?

Una única pregunta, elemento padre seria la instancia de Vue? desde ya gracias!

no entiendo por que decis que las propiedades value y el metodo convertvalue es mejor definirlas en el hijo

chinnnnnnnnnnnnn, justo lo que pregunte en la clase pasada

Wuau que gran clase. 🤯🤯🤯🤯

Para comentar líneas de código en VSCode como lo hizo Nacho, lo pueden hacer con Ctrl+K+C, y para quitar el comentario, con Ctrl+K+U

El modo en el que se envían los valores es a traveś de la propiedad “props” y del tag html custom, practicamente es como si fueran funciones en HTML, al llamar al custom tag de Vue le pasas los parámetros tal cual como si fuera una funcion xD

<h4>Computed properties</h4>

Las propiedades computadas (computed properties) son aquellas que se generan a partir de otros valores en tiempo real. Es decir, que tenemos propiedades definidas en Data que cuando se modifiquen van a generar un valor nuevo sobre la propiedad computada.

Las propiedades computadas se definen dentro de la instancia de Vue como un objeto, y dentro se definen las propiedades en forma de función. Cuando alguna de las propiedades que componen las propiedad computada cambia, esta se actualizará automáticamente.

<h4>Watchers</h4>

Los watchers son funciones que ejecutan un código a partir del cambio de una variable. De igual manera se definen como un objeto dentro de la instancia de Vue.

El nombre del watcher tiene que ser igual al nombre de la propiedad de Data que queremos estar observando. Los watchers reciben dos parámetros, el valor viejo y el valor nuevo de la propiedad.

Dentro de el **_template _**de cada componente debe de haber solamente un componente html.

Mi mente explotó después de esta clase jaja

-las propiedades son para enviar datos desde el componente padre al componente hijo

👌

Nomenclatura para pasar datos a los componentes

En la parte logica (Javascript) Utilizamos
=unaPropiedad
Y en la parte de estructura, html, v-bind:una-propiedad,
=una-propiedad

Ejemplo:

excelente