最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vue 3 Composition API ProvideInject not working in Single File Components - Stack Overflow

programmeradmin1浏览0评论

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:

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()
            )
    },
}

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:

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()
            )
    },
}
Share Improve this question edited Jul 28, 2020 at 0:46 Sarmad asked Jul 27, 2020 at 1:08 SarmadSarmad 3252 gold badges4 silver badges15 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 8

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
    };
  },
};


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.

[Vue warn]: inject() can only be used inside setup() or functional components.

I had the same warning shown while using vue-router inside the pinia store,just had to bring initialization of pinia and router upfront of and try to rearrange it.

I was trying to call pinia store actions inside router main.js file even before router was initialized.

I was calling a toast action added in another store to this store enter image description here

earlier it was like this enter image description here

changed to enter image description here

发布评论

评论列表(0)

  1. 暂无评论