Vue.js

Vuejs

Tutorial Vuejs: Props y comunicación entre componentes

Vue.js: Aprende a usar props para la comunicación entre componentes en Vue. Define, usa y valida props de manera efectiva. Mejora tus habilidades en Vue.js.

Aprende Vuejs GRATIS y certifícate

Introducción a las Props en Vuejs

En Vue.js, las props (abreviación de propiedades) son un mecanismo clave para la comunicación entre componentes. Permiten que un componente padre pase datos a un componente hijo, facilitando así la creación de interfaces de usuario complejas y reutilizables. Las props se definen en el componente hijo y se les asignan valores desde el componente padre.

Para entender cómo funcionan las props, es esencial conocer algunos conceptos fundamentales:

  1. Definición de props en el componente hijo: En un componente hijo, se definen las props que se esperan recibir utilizando la opción props dentro del objeto de configuración del componente. Esta opción puede ser un array de nombres de props o un objeto que especifica el tipo y otras opciones de validación.
    // Definición básica de props como array
    export default {
      props: ['title', 'content']
    }

    // Definición avanzada de props como objeto con tipos y validación
    export default {
      props: {
        title: {
          type: String,
          required: true
        },
        content: {
          type: String,
          default: ''
        }
      }
    }
  1. Pasar props desde el componente padre: Al usar un componente hijo dentro de un componente padre, se pasan las props utilizando atributos en la instancia del componente hijo. Los valores pueden ser literales o ser evaluados como expresiones.
    <!-- Componente padre -->
    <template>
      <Child-Component title="Hola, Mundo!" :content="dynamicContent" />
    </template>

    <script>
    import ChildComponent from './ChildComponent.vue';

    export default {
      components: {
        ChildComponent
      },
      data() {
        return {
          dynamicContent: 'Este es un contenido dinámico'
        };
      }
    }
    </script>
  1. Acceso a props en el componente hijo: Dentro del componente hijo, las props se pueden acceder directamente en la plantilla o en el script como cualquier otra propiedad de datos.
    <!-- Componente hijo -->
    <template>
      <div>
        <h1>{{ title }}</h1>
        <p>{{ content }}</p>
      </div>
    </template>

    <script>
    export default {
      props: {
        title: String,
        content: String
      }
    }
    </script>

Reactividad de las props: Las props en Vue.js son reactivas, lo que significa que si el valor de una prop cambia en el componente padre, el cambio se reflejará automáticamente en el componente hijo. Sin embargo, es importante recordar que las props son de solo lectura en el componente hijo. Intentar modificar una prop directamente resultará en una advertencia de Vue en el modo de desarrollo.

Pasar funciones como props: Además de datos primitivos y objetos, también se pueden pasar funciones como props. Esto es útil para delegar eventos o lógica específica desde el componente hijo al componente padre.

    <!-- Componente padre -->
    <template>
      <Child-Component :onClick="handleClick" />
    </template>

    <script>
    import ChildComponent from './ChildComponent.vue';

    export default {
      components: {
        ChildComponent
      },
      methods: {
        handleClick() {
          console.log('El botón ha sido clicado');
        }
      }
    }
    </script>

    <!-- Componente hijo -->
    <template>
      <button @click="onClick">Clicar</button>
    </template>

    <script>
    export default {
      props: {
        onClick: Function
      }
    }
    </script>

Las props son esenciales para la arquitectura de componentes en Vue.js, facilitando la creación de componentes modulares y reutilizables. Entender su uso y limitaciones es crucial para desarrollar aplicaciones Vue.js robustas y mantenibles.

Declaración y Uso de Props

En Vue.js, la declaración y uso de props en un componente hijo se realiza mediante la opción props en el objeto de configuración del componente. Las props permiten que un componente hijo reciba datos desde su componente padre. Para definir props, se pueden utilizar dos enfoques principales: un array de nombres de props o un objeto que especifica el tipo y otras opciones de validación.

Declaración de props

  1. Definición básica de props: Utilizando un array de nombres de props, se puede definir de manera sencilla qué props se esperan recibir.
export default {
  props: ['title', 'content']
}
  1. Definición avanzada de props: Utilizando un objeto, se pueden definir propiedades con tipos y configuraciones adicionales como required, default y validator.
export default {
  props: {
    title: {
      type: String,
      required: true
    },
    content: {
      type: String,
      default: ''
    }
  }
}

Uso de props en el componente hijo

Una vez declaradas, las props se pueden utilizar dentro del componente hijo de varias maneras:

  1. En la plantilla: Las props se pueden acceder directamente en la plantilla del componente hijo.
<template>
  <div>
    <h1>{{ title }}</h1>
    <p>{{ content }}</p>
  </div>
</template>

<script>
export default {
  props: {
    title: String,
    content: String
  }
}
</script>
  1. En el script: Las props también se pueden utilizar en las opciones del script del componente, como en métodos, computadas, etc.
export default {
  props: {
    title: {
      type: String,
      required: true
    },
    content: {
      type: String,
      default: ''
    }
  },
  computed: {
    formattedContent() {
      return this.content.toUpperCase();
    }
  }
}

Pasar props desde el componente padre

Para pasar props desde el componente padre, se utilizan atributos en la instancia del componente hijo. Los valores pueden ser literales o ser evaluados como expresiones.

<!-- Componente padre -->
<template>
  <Child-Component title="Hola, Mundo!" :content="dynamicContent" />
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      dynamicContent: 'Este es un contenido dinámico'
    };
  }
}
</script>

Reactividad y restricciones de las props

Las props en Vue.js son reactivas, lo que significa que cualquier cambio en el valor de una prop en el componente padre se reflejará automáticamente en el componente hijo. Sin embargo, es esencial recordar que las props son de solo lectura en el componente hijo. Intentar modificar una prop directamente resultará en una advertencia de Vue en el modo de desarrollo.

Para modificar una prop, se recomienda emitir un evento desde el componente hijo y manejar la actualización en el componente padre.

<!-- Componente hijo -->
<template>
  <div>
    <button @click="$emit('update-title', 'Nuevo Título')">Actualizar Título</button>
  </div>
</template>

<script>
export default {
  props: ['title']
}
</script>

<!-- Componente padre -->
<template>
  <ChildComponent :title="title" @update-title="updateTitle" />
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      title: 'Título Inicial'
    };
  },
  methods: {
    updateTitle(newTitle) {
      this.title = newTitle;
    }
  }
}
</script>

Este enfoque asegura que la fuente de verdad de los datos permanezca en el componente padre mientras se mantiene la reactividad y la integridad de los datos en la aplicación.

Tipos de Props y Validación

En Vue.js, definir el tipo de las props y aplicar validaciones es fundamental para asegurar que los componentes reciban los datos esperados y funcionen correctamente. A continuación, se detalla cómo definir tipos de props y realizar validaciones avanzadas.

Definición de tipos de props: Vue permite especificar tipos de props para asegurar que los datos pasados al componente hijo sean del tipo esperado. Los tipos más comunes incluyen String, Number, Boolean, Array, Object, Function, y Symbol.

export default {
  props: {
    title: String, // Espera un String
    age: Number, // Espera un Number
    isActive: Boolean, // Espera un Boolean
    items: Array, // Espera un Array
    user: Object, // Espera un Object
    callback: Function, // Espera una Function
    uniqueId: Symbol // Espera un Symbol
  }
}

Propiedades adicionales de validación: Además del tipo, Vue permite definir propiedades adicionales para cada prop, como required, default y validator.

  • required: Indica que una prop es obligatoria.
  • default: Especifica un valor por defecto si la prop no se pasa.
  • validator: Permite definir una función de validación personalizada.
export default {
  props: {
    title: {
      type: String,
      required: true // La prop title es obligatoria
    },
    age: {
      type: Number,
      default: 18 // Si no se pasa, age será 18
    },
    items: {
      type: Array,
      default: () => [] // Valor por defecto como función que retorna un array vacío
    },
    user: {
      type: Object,
      validator(value) {
        // La prop user debe tener las propiedades name y email
        return 'name' in value && 'email' in value;
      }
    }
  }
}

Validación personalizada: La propiedad validator permite realizar validaciones más complejas. La función de validación recibe el valor de la prop y debe retornar true si el valor es válido, o false en caso contrario.

export default {
  props: {
    age: {
      type: Number,
      validator(value) {
        // La prop age debe ser un número entre 0 y 120
        return value >= 0 && value <= 120;
      }
    },
    email: {
      type: String,
      validator(value) {
        // La prop email debe ser una dirección de correo válida
        const emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
        return emailPattern.test(value);
      }
    }
  }
}

Combinación de propiedades: Es posible combinar varias propiedades de validación en una misma prop para asegurar que los datos recibidos cumplan con múltiples criterios.

export default {
  props: {
    username: {
      type: String,
      required: true, // La prop username es obligatoria
      default: 'Anonymous', // Valor por defecto si no se pasa
      validator(value) {
        // La prop username debe tener entre 3 y 15 caracteres
        return value.length >= 3 && value.length <= 15;
      }
    }
  }
}

Propiedades con valores por defecto basados en funciones: Para props que son objetos o arrays, es recomendable definir valores por defecto mediante funciones para evitar que todos los componentes compartan la misma instancia del objeto o array.

export default {
  props: {
    config: {
      type: Object,
      default: () => ({ theme: 'dark', layout: 'grid' }) // Valor por defecto como función que retorna un objeto
    }
  }
}

Validación de props en componentes padres: Aunque Vue proporciona mecanismos robustos para la validación de props en el componente hijo, es una buena práctica validar los datos en el componente padre antes de pasarlos al hijo para evitar errores y asegurar la integridad de los datos.

<template>
  <Child-Component :age="validatedAge" />
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      ageInput: 25
    };
  },
  computed: {
    validatedAge() {
      // Validación en el componente padre
      return this.ageInput >= 0 && this.ageInput <= 120 ? this.ageInput : 18;
    }
  }
}
</script>

Este enfoque asegura que los componentes hijos reciban datos ya validados, simplificando su lógica y reduciendo la posibilidad de errores en la aplicación.

Manipulación de Datos Recibidos como Props

En Vue.js, aunque las props son de solo lectura y no deben modificarse directamente en el componente hijo, existen patrones y técnicas para manipular los datos recibidos como props de manera segura y efectiva.

Copia de props a datos locales

Una técnica común es copiar el valor de una prop a una propiedad de datos local en el componente hijo. Esto permite modificar y trabajar con el valor sin afectar directamente la prop original. Este enfoque es útil cuando se necesita una versión mutable del dato.

export default {
  props: {
    initialCount: {
      type: Number,
      required: true
    }
  },
  data() {
    return {
      count: this.initialCount
    };
  },
  methods: {
    increment() {
      this.count++;
    }
  }
}

Uso de computadas para transformar props

Las propiedades computadas (computed properties) son útiles para derivar valores basados en las props. Las computadas son reactivas y se recalculan automáticamente cuando cambian las dependencias. Esto permite transformar y manipular los datos recibidos sin modificar las props directamente.

export default {
  props: {
    items: {
      type: Array,
      required: true
    }
  },
  computed: {
    sortedItems() {
      return this.items.slice().sort((a, b) => a.value - b.value);
    }
  }
}

Emitir eventos para actualizar props

Si se necesita actualizar una prop, la forma recomendada es emitir un evento desde el componente hijo y manejar la actualización en el componente padre. Este patrón mantiene la fuente de verdad en el componente padre y asegura que los cambios sean reactivos.

<!-- ChildComponent.vue -->
<template>
  <div>
    <button @click="updateTitle">Actualizar Título</button>
  </div>
</template>

<script>
export default {
  props: {
    title: {
      type: String,
      required: true
    }
  },
  methods: {
    updateTitle() {
      this.$emit('update:title', 'Nuevo Título');
    }
  }
}
</script>

<!-- Componente padre -->
<template>
  <Child-Component :title="title" @update:title="setTitle" />
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      title: 'Título Inicial'
    };
  },
  methods: {
    setTitle(newTitle) {
      this.title = newTitle;
    }
  }
}
</script>

Validación y manipulación de datos

En algunos casos, es necesario validar y manipular los datos recibidos como props antes de utilizarlos. Esto se puede hacer en una propiedad computada o en un método, asegurando que los datos sean consistentes y válidos.

export default {
  props: {
    rawData: {
      type: Object,
      required: true
    }
  },
  computed: {
    processedData() {
      // Validar y transformar los datos
      if (!this.rawData || typeof this.rawData !== 'object') {
        return {};
      }
      return {
        ...this.rawData,
        processed: true
      };
    }
  }
}

Estas técnicas permiten trabajar con datos recibidos como props de manera flexible y segura, respetando las restricciones de solo lectura de las props y manteniendo la reactividad y la integridad de los datos en la aplicación Vue.js.

Ejemplos de comunicación entre componentes

En Vue.js, la comunicación entre componentes se puede realizar de varias maneras. A continuación, se presentan ejemplos de cómo se puede hacer esto utilizando props, eventos, y la API de inyección/provisión.

Comunicación del componente padre al hijo

La forma más común de comunicación del componente padre al hijo es mediante el uso de props. El componente padre pasa datos al componente hijo a través de atributos personalizados.

<!-- Componente padre -->
<template>
  <Child-Component :message="parentMessage" />
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentMessage: 'Mensaje del padre'
    };
  }
}
</script>

<!-- Componente hijo -->
<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  props: {
    message: {
      type: String,
      required: true
    }
  }
}
</script>

Comunicación del componente hijo al padre

La comunicación del componente hijo al padre se realiza comúnmente mediante la emisión de eventos. El componente hijo emite un evento que el componente padre escucha y maneja.

<!-- Componente hijo -->
<template>
  <button @click="notifyParent">Notificar al Padre</button>
</template>

<script>
export default {
  methods: {
    notifyParent() {
      this.$emit('notify', 'Mensaje del hijo');
    }
  }
}
</script>

<!-- Componente hijo -->
<template>
  <Child-Component @notify="handleNotification" />
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  methods: {
    handleNotification(message) {
      console.log(message); // 'Mensaje del hijo'
    }
  }
}
</script>

Comunicación entre componentes hermanos

Para la comunicación entre componentes hermanos, se puede utilizar un patrón basado en un EventBus o una instancia de Vue para emitir y escuchar eventos. Sin embargo, en aplicaciones más grandes, es recomendable usar soluciones como Vuex para la gestión de estado global.

// EventBus.js
import Vue from 'vue';
export const EventBus = new Vue();
<!-- Hermano uno -->
<template>
  <button @click="sendMessage">Enviar Mensaje</button>
</template>

<script>
import { EventBus } from './EventBus';

export default {
  methods: {
    sendMessage() {
      EventBus.$emit('message', 'Mensaje de SiblingOne');
    }
  }
}
</script>

<!-- Hermano dos -->
<template>
  <div>{{ receivedMessage }}</div>
</template>

<script>
import { EventBus } from './EventBus';

export default {
  data() {
    return {
      receivedMessage: ''
    };
  },
  created() {
    EventBus.$on('message', (message) => {
      this.receivedMessage = message;
    });
  }
}
</script>

Estos ejemplos cubren los métodos más comunes de comunicación entre componentes en Vue.js, permitiendo la creación de aplicaciones modulares y bien estructuradas.

Aprende Vuejs GRATIS online

Ejercicios de esta lección Props y comunicación entre componentes

Evalúa tus conocimientos de esta lección Props y comunicación entre componentes con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Todas las lecciones de Vuejs

Accede a todas las lecciones de Vuejs y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Vue Y Su Ecosistema

Vue.js

Introducción Y Entorno

Instalar Y Configurar Vue Con Vite

Vue.js

Introducción Y Entorno

Introducción A La Sintaxis De Plantillas

Vue.js

Componentes

Introducción A Componentes

Vue.js

Componentes

Componentes Con Options Api

Vue.js

Componentes

Componentes Con Composition Api

Vue.js

Componentes

Renderizado Condicional Con V-if

Vue.js

Componentes

Renderizado Iterativo Con V-for

Vue.js

Componentes

Props Y Comunicación Entre Componentes

Vue.js

Componentes

Manejo De Eventos En Vue Con V-on

Vue.js

Componentes

Binding Bidireccional Con V-model Y Definemodel

Vue.js

Componentes

Estilización De Componentes

Vue.js

Componentes

Reactividad Con Ref Y Reactive

Vue.js

Composición Y Reactividad

Ciclo De Vida Con Composition Api

Vue.js

Composición Y Reactividad

Composition Api: Provide E Inject

Vue.js

Composición Y Reactividad

Introducción A Los Composables

Vue.js

Composición Y Reactividad

Uso Avanzado De Composables

Vue.js

Composición Y Reactividad

Introducción A Vue Router

Vue.js

Navegación Y Enrutamiento

Definición Y Manejo De Rutas

Vue.js

Navegación Y Enrutamiento

Rutas Anidadas Y Dinámicas

Vue.js

Navegación Y Enrutamiento

Navegación Programática Y Redirección

Vue.js

Navegación Y Enrutamiento

Solicitudes Http Con Fetch Api

Vue.js

Interacción Http Con Apis De Backend

Solicitudes Http Con Axios

Vue.js

Interacción Http Con Apis De Backend

Introducción A Suspense

Vue.js

Interacción Http Con Apis De Backend

Evaluación Test De Conocimientos Vuejs

Vue.js

Evaluación

Accede GRATIS a Vuejs y certifícate

Certificados de superación de Vuejs

Supera todos los ejercicios de programación del curso de Vuejs y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.

En esta lección

Objetivos de aprendizaje de esta lección

  1. Definir y tipificar props en componentes hijos.
  2. Pasar datos desde componentes padres a componentes hijos.
  3. Acceder y utilizar props en componentes hijos.
  4. Mantener la reactividad de props sin modificarlas directamente.
  5. Emitir eventos desde el componente hijo al padre para actualizar props.
  6. Validar props y utilizar validaciones personalizadas.
  7. Manejar datos recibidos como props de manera segura.