Vue 3 Composition API Provide/Inject not working in Single File Components

10,580

Solution 1

For anyone having the same issue, the code had no problem. The problem was the difference in version for 'vue' and '@vue/compiler-sfc' (Vue compiler for Single File Component) in my package.json file.

enter image description here

Solution 2

I had the same warning and issue when using async setup()

inject() can only be used inside setup() or functional components.

The problem was having an async call before the inject was initialised, I am not sure why it matters.

The solution was declaring the inject before the async function is being called.


import getCharacters from "../composables/characters";
import { inject } from "vue";
export default {
  async setup() {
    const store = inject("store");
    const { characters } = await getCharacters();
    
    store.updateChars(characters)

    return {
      characters,
      store
    };
  },
};


Share:
10,580

Related videos on Youtube

Sarmad
Author by

Sarmad

Updated on June 01, 2022

Comments

  • Sarmad
    Sarmad almost 2 years

    I'm making a library in VueJS 3 using Composition API. I implemented Provide/Inject as mentioned in docs. But the property in child component is still undefined and I get following error in browser console:

    Console Output

    A very simple implementation of my code is as follow:

    Usage In Project

    <ThemeProvider>
        <Button color="green">
            ABC
        </Button>
    </ThemeProvider>
    
    <script>
        import { ThemeProvider, Button } from 'my-library'
    
        export default {
            name: 'SomePage',
            setup() {...},
        }
    </script>
    

    ThemeProvider.js (Parent Componen)

    import { toRefs, reactive, provide, h } from 'vue'
    
    export default {
        name: 'theme-provider',
        props:
            theme: {
                type: Object,
                default: () => ({...}),
            },
        },
        setup(props, { slots }) {
            const { theme } = toRefs(props)
    
            provide('theme', reactive(theme.value))
    
            return () =>
                h(
                    'div',
                    {...},
                    slots.default()
                )
        },
    }
    

    Button.js (Child Component)

    import { inject, h } from 'vue'
    
    export default {
        name: 'Button',
        setup(props, { slots }) {
            const theme = inject('theme')
            console.log(theme)  // returns undefined
    
            return () =>
                h(
                    'button',
                    {...},
                    slots.default()
                )
        },
    }
    
  • Zack Weiner
    Zack Weiner over 3 years
    To extend that a little bit: You can declare the variable as an initialized ref before running the async function inside of setup() and then assign ref.value = result after the awaited call returns. i.e. const myRef = ref(""); let result = await asyncMethod(); myRef.value = result;
  • dotNET
    dotNET about 2 years
    Should be the accepted answer. Worked for me in script setup syntax too.