Comunicar componentes con Vue 3 y pinia

En Vue 3 se pueden comunicar componentes de padre a hijo con las propiedades (props), defineEmit y defineExpose.

Voy a dejar esa comunicación de componentes simples (padre a hijo o viceversa) para otro post, ahora quiero enfocarme en comunicar componentes sin importar lo “separados” que estén, invocando funciones de otros componentes desde cualquier componente.

Por ejemplo, vamos a ver cómo comunicar componentes hermanos, nietos, etcétera. Comunicar componentes de Vue 3 sin usar emit ni expose, para ello vamos a usar una store de Pinia.

La store de Pinia

Pinia permite tener stores que sirven para mantener y sincronizar el estado a través de varios componentes, pero en este caso yo no solo quiero sincronizar el estado; quiero invocar una función de un componente desde cualquier otro componente de Vue.

Para ello he utilizado $onAction de pinia, que permite escuchar cuando se invoca a una función de la store. Veamos cómo hacerlo a continuación.

Creando la store

La store de pinia para comunicar los componentes es muy simple. Dentro de la store debes definir las funciones (acciones) opcionalmente sin cuerpo. Aquí un ejemplo:

import { defineStore } from "pinia";

export const useCommunicationStore = defineStore('communication', () => {
    function enfocarInput(): undefined {
        
    }
    return { enfocarInput };
});

Tengo la acción enfocarInput que no tiene cuerpo, pero que está expuesta. No necesita hacer nada, ya que solo va a funcionar como un listener. Luego, en $onAction voy a revisar el nombre de la función desde el componente.

Emitiendo evento

El componente que va a invocar a la función de otro componente de Vue 3 debe importar la store:

import { useCommunicationStore } from "@/stores/comunicacionEntreComponentes";
const communicationStore = useCommunicationStore();

Después, para invocar a la función del otro componente, simplemente hay que invocar a la acción de la store, en este caso sería la de enfocarInput:

communicationStore.enfocarInput();

Escuchando evento

Ahora vayamos al otro componente donde queremos escuchar la invocación. Igualmente importamos la store:

import { useCommunicationStore } from '@/stores/comunicacionEntreComponentes';
const communicationStore = useCommunicationStore();

Agregamos un callback al $onAction de dicha store y revisamos el nombre de la acción:

communicationStore.$onAction((detalles) => {
    if (detalles.name === "enfocarInput") {
        // La función fue invocada desde otro componente. Haz algo
    }
});

De este modo podemos invocar a funciones entre componentes de Vue 3. La ventaja es que cualquier número de componentes pueden suscribirse a distintas acciones usando la misma store y podemos propagar globalmente todas estas invocaciones como si fuera un evento.

Más información sobre $onAction de Pinia: https://pinia.vuejs.org/core-concepts/actions.html#Subscribing-to-actions

¿Por qué no usar $subscribe o watch?

Lo que yo quería era invocar a una función de un componente desde cualquier componente. $subscribe permite suscribirte a las mutaciones de la store, y para ello tendría que mutar el estado, pero aquí no me interesa el estado, me interesa saber que alguien está invocando a la función.

Con watch podría hacerse casi lo mismo que hice, pero tendríamos que incluir una variable de estado y no sería tan idiomático.

Decidí hacerlo vigilando las acciones porque así puedo saber cuál función se ha invocado.

Si tú sabes otra forma de comunicar cualquier componente de Vue 3 con Pinia, invocando a una función de otro componente, déjalo en los comentarios.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *