Vue.js

Vuejs

Tutorial Vuejs: Composition API: provide e inject

Aprende en Vue el uso avanzado de Composition API con provide e inject para compartir datos y funciones entre componentes de forma eficiente y reactiva.

Aprende Vuejs GRATIS y certifícate

Introducción a provide e inject y para qué sirven

En Vue, la Composition API introduce una forma de compartir datos entre componentes padre e hijo sin necesidad de pasar props de forma explícita a través de cada nivel de la jerarquía de componentes. 

Las funciones provide e inject permiten a un componente proporcionar datos que pueden ser consumidos por sus descendientes, facilitando la reusabilidad y la organización del código.

provide se utiliza en el componente padre para especificar qué datos estarán disponibles para sus componentes hijos. Los datos proporcionados pueden ser valores primitivos, objetos reactivos, o funciones. Por otro lado, inject se usa en los componentes hijos para acceder a los datos proporcionados por un componente ancestro. Esto es especialmente útil en aplicaciones con estructuras de componentes complejas donde pasar props a través de muchos niveles puede volverse engorroso.

Ejemplo básico:

<!-- Componente padre -->
<template>
  <mi-componente />
</template>

<script setup lang="ts">
import MiComponente from './components/mi-componente.vue';

import { provide, ref } from 'vue';

const sharedData = ref('Este es un dato compartido');
provide('sharedData', sharedData);
</script>
<!-- Componente hijo -->
<template>
  <p>{{ sharedData }}</p>
</template>

<script setup lang="ts">
import { inject } from 'vue';

const sharedData = inject<string>('sharedData');
</script>

En este ejemplo, el componente padre utiliza provide para compartir sharedData con todos sus componentes hijos. El componente hijo utiliza inject para acceder a sharedData.

Las principales ventajas de provide e inject incluyen:

  1. Encapsulación de datos: Permiten encapsular datos y lógica en componentes específicos sin necesidad de pasar props a través de múltiples niveles de componentes.
  2. Manejo de estados globales: Son útiles para manejar estados globales o configuraciones que deben ser accesibles por varios componentes en la jerarquía.
  3. Reusabilidad: Facilitan la creación de componentes reusables y modulares al permitir que los datos y la lógica se compartan de manera más eficiente.

Es importante tener en cuenta que el uso de provide e inject debe ser limitado a casos donde realmente se necesite compartir datos a través de varios niveles de componentes. Para la mayoría de los casos, el paso de props y la elevación de eventos sigue siendo una práctica adecuada y más clara.

Uso básico de provide e inject en la Composition API

Para utilizar provide e inject en la Composition API de Vue, primero debemos entender cómo configurar estos mecanismos en un componente padre y sus componentes descendientes. A continuación, se muestra cómo se realiza este proceso:

Configuración del componente padre con provide:

En el componente padre, utilizamos la función provide dentro del setup para especificar los datos que queremos compartir. La clave es una cadena de texto o un símbolo que identificará los datos, mientras que el valor puede ser cualquier tipo de dato, como un valor primitivo, un objeto reactivo o incluso una función.

import { provide, ref } from 'vue';

export default {
  setup() {
    const sharedData = ref('Este es un dato compartido');
    const sharedFunction = (val) => `Valor procesado: ${val}`;
    
    provide('sharedData', sharedData);
    provide('sharedFunction', sharedFunction);
    
    return {};
  }
}

En este ejemplo, sharedData es un dato reactivo que se proporciona a los componentes hijos, al igual que sharedFunction, que es una función.

Acceso a los datos en el componente hijo con inject:

En el componente hijo, utilizamos la función inject dentro del setup para acceder a los datos proporcionados por el componente ancestro. Usamos la misma clave que se utilizó en provide.

import { inject } from 'vue';

export default {
  setup() {
    const sharedData = inject('sharedData');
    const sharedFunction = inject('sharedFunction');
    
    return {
      sharedData,
      sharedFunction
    };
  }
}

Aquí, el componente hijo accede a sharedData y sharedFunction proporcionados por el componente padre.

Uso de los datos inyectados en la plantilla del componente hijo:

Podemos utilizar los datos inyectados directamente en la plantilla del componente hijo para mostrar información o llamar a funciones.

<template>
  <div>
    <p>Dato compartido: {{ sharedData }}</p>
    <p>{{ sharedFunction('un valor de prueba') }}</p>
  </div>
</template>

<script>
import { inject } from 'vue';

export default {
  setup() {
    const sharedData = inject('sharedData');
    const sharedFunction = inject('sharedFunction');
    
    return {
      sharedData,
      sharedFunction
    };
  }
}
</script>

En este ejemplo, sharedData se muestra directamente en la plantilla, y sharedFunction se llama con un argumento, mostrando el valor procesado.

Reactividad de los datos inyectados:

Es importante notar que si el valor proporcionado es reactivo (como en el caso de sharedData), los cambios en este valor se reflejarán automáticamente en los componentes que lo inyectan.

import { provide, ref, watch } from 'vue';

export default {
  setup() {
    const sharedData = ref('Dato inicial');
    provide('sharedData', sharedData);
    
    // Simulamos una actualización del dato compartido después de 2 segundos
    setTimeout(() => {
      sharedData.value = 'Dato actualizado';
    }, 2000);

    return {};
  }
}

En el componente hijo, al ser sharedData reactivo, la actualización del dato después de 2 segundos se reflejará automáticamente en la vista.

El uso de provide e inject es una técnica eficaz para compartir datos y lógica entre componentes en Vue, sin la necesidad de pasar props a través de múltiples niveles de la jerarquía de componentes. Esto permite mantener el código más limpio y modular.

Uso avanzado de provide e inject en la Composition API

En Vue 3, la Composition API ofrece un control más granular y flexible sobre la reactividad y la organización del código. Al usar provide e inject, podemos compartir datos y funcionalidades entre componentes de una manera más sofisticada. En esta sección, exploraremos usos avanzados de provide e inject que incluyen la manipulación de datos reactivos, la inyección de múltiples valores y el uso de valores por defecto.

1. Reactividad avanzada con provide e inject:

Cuando usamos objetos reactivos con provide e inject, podemos aprovechar las capacidades de reactividad de Vue para hacer cambios dinámicos en los datos compartidos. Por ejemplo, podemos proporcionar un objeto reactivo y permitir que los componentes hijos lo modifiquen.

// Componente padre
import { provide, reactive } from 'vue';

export default {
  setup() {
    const sharedState = reactive({
      count: 0,
      message: 'Inicial'
    });

    provide('sharedState', sharedState);

    return {};
  }
}
// Componente hijo
import { inject } from 'vue';

export default {
  setup() {
    const sharedState = inject('sharedState');

    const increment = () => {
      sharedState.count++;
    };

    return {
      sharedState,
      increment
    };
  }
}
<!-- Plantilla del componente hijo -->
<template>
  <div>
    <p>Contador: {{ sharedState.count }}</p>
    <p>Mensaje: {{ sharedState.message }}</p>
    <button @click="increment">Incrementar</button>
  </div>
</template>

En este ejemplo, sharedState es un objeto reactivo proporcionado por el componente padre. El componente hijo puede acceder y modificar este estado, y los cambios se reflejan en todos los componentes que inyectan sharedState.

2. Inyección de múltiples valores:

Podemos proporcionar e inyectar múltiples valores utilizando diferentes claves. Esto permite compartir distintos tipos de datos o funcionalidades.

// Componente padre
import { provide, ref } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const message = ref('Hola Mundo');

    provide('count', count);
    provide('message', message);

    return {};
  }
}
// Componente hijo
import { inject } from 'vue';

export default {
  setup() {
    const count = inject('count');
    const message = inject('message');

    return {
      count,
      message
    };
  }
}
<!-- Plantilla del componente hijo -->
<template>
  <div>
    <p>Contador: {{ count }}</p>
    <p>Mensaje: {{ message }}</p>
  </div>
</template>

Aquí, count y message son valores separados proporcionados por el componente padre y accesibles en el componente hijo mediante claves diferentes.

3. Uso de valores por defecto:

Cuando un componente hijo intenta inyectar un valor que no ha sido proporcionado, podemos especificar un valor por defecto. Esto es útil para asegurar que los componentes funcionen correctamente incluso si los valores esperados no están disponibles.

// Componente hijo con valor por defecto
import { inject } from 'vue';

export default {
  setup() {
    const count = inject('count', 0);
    const message = inject('message', 'Valor por defecto');

    return {
      count,
      message
    };
  }
}

En este ejemplo, si count o message no son proporcionados por un componente ancestro, los valores por defecto (0 y 'Valor por defecto') serán utilizados.

4. Inyección de funciones y métodos:

Además de valores y objetos, también podemos proporcionar e inyectar funciones. Esto permite que los componentes hijos ejecuten lógica definida en los componentes padres.

// Componente padre
import { provide } from 'vue';

export default {
  setup() {
    const logMessage = (msg) => {
      console.log(`Mensaje desde el padre: ${msg}`);
    };

    provide('logMessage', logMessage);

    return {};
  }
}
// Componente hijo
import { inject } from 'vue';

export default {
  setup() {
    const logMessage = inject('logMessage');

    const sendMessage = () => {
      logMessage('Hola desde el hijo');
    };

    return {
      sendMessage
    };
  }
}
<!-- Plantilla del componente hijo -->
<template>
  <button @click="sendMessage">Enviar mensaje</button>
</template>

En este ejemplo, logMessage es una función proporcionada por el componente padre, que el componente hijo puede inyectar y utilizar para enviar mensajes al padre.

Estos ejemplos muestran cómo provide e inject pueden ser utilizados de manera avanzada para crear aplicaciones Vue más modulares y mantenibles. La flexibilidad de la Composition API permite estructurar el código de una manera que facilita la reusabilidad y la gestión de estados compartidos.

Aprende Vuejs GRATIS online

Ejercicios de esta lección Composition API: provide e inject

Evalúa tus conocimientos de esta lección Composition API: provide e inject 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. Comprender cómo provide e inject permiten compartir datos entre componentes sin necesidad de pasar props a través de la jerarquía.
  2. Implementar provide e inject utilizando valores primitivos, objetos reactivos y funciones.
  3. Manejar estados y datos globales utilizando provide e inject.
  4. Emplear técnicas avanzadas como la reactividad avanzada, la inyección de múltiples valores y el uso de valores por defecto.
  5. Incorporar funciones y métodos a través de provide e inject para modularizar la lógica de la aplicación.