vuejs-provide-inject

Qué son y cómo usar Provide e Inject en Vue.js

  • 3 min

En Vue,js, provide e inject son dos funciones de que permiten compartir datos entre componentes en una jerarquía profunda.

Ya hemos visto que la forma habitual para pasar datos y variables de un componente padre a un componente hijo, es utilizar props.

Sin embargo, si hay múltiples niveles de componentes anidados, pasarlo de un componente a otro, y al otro, y al otro, se puede convertir en un engorro.

A ese problema se le denomina prop drilling, y acaba convirtiéndose en un pequeño dolor de sintaxis.

Para mejorar esto Vue proporciona provide e inject, como alternativa al uso de props para pasar datos entre componentes sin pasar manualmente a través de cada nivel.

¿Qué son provide e inject?

Las palabras clave provide e inject forman parte de un mecanismo que nos permite compartir datos entre componentes,

  • provide: Se usa en un componente padre para proveer datos o métodos que estarán disponibles para todos sus componentes descendientes.
  • inject: Se usa en un componente hijo para inyectar los datos o métodos proporcionados por un componente ancestro.

Vamos a verlo con un ejemplo

<template>
  <div>
    <ChildComponent />
  </div>
</template>

<script setup>
import { provide } from 'vue';
import ChildComponent from './ChildComponent.vue';

const message = 'Hola desde el componente padre';
provide('message', message); // Provee el valor 'message'
</script>
<template>
  <div>
    <p>Mensaje recibido: {{ injectedMessage }}</p>
  </div>
</template>

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

const injectedMessage = inject('message'); // Inyecta el valor 'message'
</script>

En este ejemplo:

  • El componente padre (ParentComponent) provee un valor (message) usando provide.
  • El componente hijo (ChildComponent) inyecta el valor usando inject y lo muestra en su template.

Valores por defecto en inject

<template>
  <div>
    <p>Mensaje recibido: {{ injectedMessage }}</p>
  </div>
</template>

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

const injectedMessage = inject('message', 'Valor por defecto'); // Valor por defecto
</script>

En este ejemplo:

  • Si el valor message no está disponible, se usa el valor por defecto 'Valor por defecto'.

Proveer e inyectar datos reactivos

Los datos proporcionados con provide pueden ser reactivos, lo que significa que los cambios en los datos se reflejarán automáticamente en los componentes que los inyectan.

<template>
  <div>
    <ChildComponent />
    <button @click="changeMessage">Cambiar mensaje</button>
  </div>
</template>

<script setup>
import { provide, ref } from 'vue';
import ChildComponent from './ChildComponent.vue';

const message = ref('Hola desde el componente padre');
provide('message', message); // Provee el valor reactivo 'message'

function changeMessage() {
  message.value = '¡Mensaje cambiado!';
}
</script>
<template>
  <div>
    <p>Mensaje recibido: {{ injectedMessage }}</p>
  </div>
</template>

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

const injectedMessage = inject('message'); // Inyecta el valor reactivo 'message'
</script>

En este ejemplo:

  • El componente padre provee un valor reactivo (message) usando provide.
  • El componente hijo inyecta el valor reactivo y lo muestra en su template.
  • Cuando el botón en el componente padre cambia el mensaje, el componente hijo se actualiza automáticamente.

Proveer e inyectar métodos

Además de datos, también puedes proveer e inyectar métodos. Esto es útil para compartir funcionalidades entre componentes.

<template>
  <div>
    <ChildComponent />
  </div>
</template>

<script setup>
import { provide } from 'vue';
import ChildComponent from './ChildComponent.vue';

function showAlert() {
  alert('¡Este es un método proporcionado por el componente padre!');
}

provide('showAlert', showAlert); // Provee el método 'showAlert'
</script>
<template>
  <div>
    <button @click="injectedShowAlert">Mostrar alerta</button>
  </div>
</template>

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

const injectedShowAlert = inject('showAlert'); // Inyecta el método 'showAlert'
</script>

En este ejemplo:

  • El componente padre provee un método (showAlert) usando provide.
  • El componente hijo inyecta el método y lo usa en un botón.