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.