Skip to content
Advertisement

How to pass a data from a component to other route in VueJS

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.

https://pinia.vuejs.org/

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement