Search code examples
vue.jscomponentsvue-componentvue-router

Transfer Data From One Component to Another


I have a component which makes a call to my backend API. This then provides me with data that I use for the component. I now want to create another component which also uses that data. While I could just do another api call that seems wasteful.

So, in Profile.vue i have this in the created() function.

<script>
import axios from 'axios';
import { bus } from '../main';


export default {
    name: 'Profile',
    data() {
        return {
            loading: false,
            error: null,
            profileData: null,
            getImageUrl: function(id) {
                return `http://ddragon.leagueoflegends.com/cdn/9.16.1/img/profileicon/` + id + `.png`;
            }
        }
    },
    beforeCreate() {
        //Add OR Remove classes and images etc..
    },
    async created() {
        //Once page is loaded do this
        this.loading = true;
        try {
            const response = await axios.get(`/api/profile/${this.$route.params.platform}/${this.$route.params.name}`);
            this.profileData = response.data;
            this.loading = false;
            bus.$emit('profileData', this.profileData)

        } catch (error) {
            this.loading = false;
            this.error = error.response.data.message;
        }
    }
};
</script>

I then have another child component that I've hooked up using the Vue router, this is to display further information.

MatchHistory compontent

<template>
  <section>
      <h1>{{profileDatas.profileDatas}}</h1>
  </section>
</template>

<script>
import  { bus } from '../main';

export default {
    name: 'MatchHistory',
    data() {
        return {
            profileDatas: null
        }
    },
    beforeCreate() {
        //Add OR Remove classes and images etc..
    },
    async created() {
        bus.$on('profileData', obj => {
            this.profileDatas = obj;
        });
    }
};
</script>

So, I want to take the info and display the data that I have transferred across.


Solution

  • My assumption is based on the fact that these components are defined for two separate routes and an event bus may not work for your situation based on the design of your application. There are several ways to solve this. Two of them listed below.

    1. Vuex (for Vue state management)
    2. Any local storage option - LocalStorage/SessionStorage/IndexDB e.t.c

    for more information on VueX, visit https://vuex.vuejs.org/.

    for more information on Localstorage, visit https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage.

    for more information on session storage, visit https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage

    The flow is pretty much the same for any of the options.

    1. Get your data from an API using axios as you did above in Profile.vue
    2. Store the retrieved data with VueX or Local/Session storage
    3. Retrieve the data from Vuex or local/session storage in the created method of MatchHistory.vue component

    For the local / session storage options, you will have to convert your object to a json string as only strings can be stored in storage. see below.

    in Profile.vue (created)

    const response = await axios.get(........)
    if(response){
        localStorage.setItem('yourstoragekey', JSON.stringify(response));
    }
    

    In MatchHistory.Vue (created)

    async created() {
        var profileData = localStorage.getItem('yourstoragekey')
        if(profileData){
            profileData = JSON.parse(profileData );
            this.profileData = profileData 
        }
    }