I have the following component structure:-
MainLayout ------------------> Pages | | |---> MyGroupList | | | | | |---> MyGroup |--> MyGroupPage | | ^ | |--onClick -----------| | | |----> MyInputBox
MainLayout has a page MyGroupPage which needs to display a list of fetched messages in a group based on the MyGroup that is being clicked. But I also want to add new messages in a particular group. To do that I have MyInputBox.
Currently the list of groups and messages in a group are being fetched by the MainLayout, I am sending the group list to the MyGroupList as props. I am emitting an event with the current group as an argument when I click on MyGroup and I bubble that event all the way to the MainLayout .
<!--In MyGroup Component-->
<q-item
clickable
v-ripple
class="q-pa-md"
@click="$emit('changedGroup', group)"
:to="{ name: 'MyGroupPage', params: { group: group.id } }"
>
<!-- In MyGroupList Component-->
<q-list bordered>
<MyGroup
v-for="group in groups"
:key="group.id"
:group="group"
@changed-group="(currGroup) => $emit('changedGroup', currGroup)"
/>
</q-list>
There I fetch the messages of that group.
I also use MyInputBox to ask for input and send that message as a event back to the MainLayout. There I am adding that new message in the list of the fetched messages.
<!-- In MainLayout Component -->
<template>
<q-layout view="lHr lpr lFr">
<MyGroupList :groups="groups" @changed-group="changeGroupHandler"/>
<q-page-container>
<router-view />
</q-page-container>
<MyInputBox @add-chat="addChat"/>
</q-layout>
</template>
<script setup>
const groups = ref([]);
fetchGroups()
.then((fetchedGroups) => (groups.value = fetchedGroups))
const messages = ref([]);
const changeGroupHandler = (currGroup) => {
fetchMessages(currGroup)
.then((fetchedMessages) => (messages.value = fetchedMessages))
}
const addMessage = mess => messages.value.push(mess);
</script>
But I am not able to figure out how to send that list of messages to the MyGroupPage.
Since the MyGroupPage page is being switched when MyGroup is clicked, Do I need to pass the updated list of messages from MainLayout again to MyGroup and send it as a route param to the MyGroupPage.
I wanted to know how to do that and If what I am doing is a good practice or not?
Earlier Instead of emitting events, I was storing the current group in a composable as a global state. How does that compare to this approach?
Advertisement
Answer
From what I understand, this seems to be a good case for using a store like Vuex: https://vuex.vuejs.org/guide/#the-simplest-store.
It offers a structure for what you are trying to achieve by sharing a state with all the components.
Since it seems tightly coupled, it will probably be easier than trying to communicate between pages in a way that will probably be hard to maintain.
edit: I found since this answer that Vuex is not the recommended solution anymore.
It is now Pinia that is recommended. For anyone wanting to add a store to a Vue.js application, it might be a better choice.