Search code examples
javascriptvue.jsvue-componentvue-clivuejs3

Data not injected from parent to child using provide/inject in VueJS


I am trying to inject data from parent to child elements using provide and inject but the data is not available in the child element. I added the same data within the component (commented), if uncommented it's visible but not the data injected.

Hello is being printed but not the passed data

TheResource.vue ---- parent

<template>
    <div>
        <base-card>
            <base-button @click.native="setSelectedTab('stored-resources')">Stored Resources</base-button>
            <base-button @click.native="setSelectedTab('add-resource')">Add Resource</base-button>
        </base-card>
        <component :is="selectedTab"></component>       
    </div>

</template>
<script>
import StoredResources from './StoredResources';
import AddResource from './AddResource';
export default {
    components:{
        StoredResources,
        AddResource
    },
    data(){
        return{
            selectedTab:'stored-resources',
            storedResources: [
                { 
                    id: 'official-guide',
                    title: 'Official Guide', 
                    description: 'The official Vue.js documentation',
                    link: 'https://vuejs.org'
                },
                {
                    id: 'google',
                    title: 'Google',
                    description: 'Learn to google.....',
                    link: 'https://google.org'
                }
            ]
        };
    }, 
    provide:{
        resources: this.storedResources
    },
    methods: {
        setSelectedTab(tab){
            console.log('Clicked')
            this.selectedTab = tab;
        }
    }
}
</script>

StoredResource.vue --- child

<template>

    <ul>
        <learning-resources v-for="res in resources" 
            :key="res.id" 
            :title="res.title" 
            :description="res.description"
            :link="res.link"></learning-resources>
        <h1>Hello</h1>
  </ul>
  
</template>
<script>
import LearningResources from './LearningResources';

export default {
   
    inject: ['resources'],
    //   data(){
    //     return{
           
    //         resources: [
    //             { 
    //                 id: 'official-guide',
    //                 title: 'Official Guide', 
    //                 description: 'The official Vue.js documentation',
    //                 link: 'https://vuejs.org'
    //             },
    //             {
    //                 id: 'google',
    //                 title: 'Google',
    //                 description: 'Learn to google.....',
    //                 link: 'https://google.org'
    //             }
    //         ]
    //     };
    // },
    components:{
        LearningResources
    }
}
</script>
<style scoped>
    ul{
        list-style: none;
        margin: 0;
        padding: 0;
        margin: auto;
        max-width: 40rem;
    }
</style>

Solution

  • From the Vue 3 docs:

    To access component instance properties, we need to convert provide to be a function returning an object

    provide() {
      return {
        resources: this.storedResources
      }
    }
    

    There is no this access unless provide is a function