search

Home  >  Q&A  >  body text

When the component is loaded, Vue's Provide and Inject are undefined.

<p><br /></p><h2>Situation</h2> <p>I'm trying to use Vue's options API for providing and injecting functionality so that the <code>header.vue</code> component can provide data to the <code>container-nav.vue</code> component ( See component hierarchy). However, when data is injected, it is undefined on initial load. </p> <p><strong>Current component hierarchy: </strong></p> <ul> <li>header.vue > header-nav-menu.vue > container-nav.vue</li> </ul> <h1>Attempt 1 - header.vue (grandparent)</h1> <p>In this component I get the following string <code>'/'</code> inside <code>Provide() {}</code> from pinia (storeCommon). </p> <pre class="brush:php;toolbar:false;">import { defineComponent } from 'vue' import parentStore from '@/store' export default defineComponent({ setup() { // Should not have access to this.navHome -> undefined (loads before options API) console.log("1. Calling setup in Header") const storeCommon = parentStore() return { storeCommon } }, beforeCreate() { // Should not have access to this.navHome -> undefined (loads before options API) console.log("2. Calling beforeCreate in Header") }, provide() { console.log("3. Calling provide in Header") return { navHome: this.storeCommon.textualData[0]?.navigation.links.home } }, created() { // Should have access to this.navHome -> '/' (loads after options API) console.log("9. Calling beforeCreate in Container Nav: ", this.$refs.navHome) }, mounted() { // Should have access to this.navHome -> '/' (loads after options API) console.log("8. Calling beforeCreate in Container Nav: ", this.$refs.navHome) } })</pre> <h1>Try 1 - container-nav.vue (child)</h1> <p>In this component, I inject the <code>navHome</code> provided by the <code>header.vue</code> component.</p> <pre class="brush:php;toolbar:false;">import { defineComponent } from 'vue' export default defineComponent({ inject: [ 'navHome' ], setup() { // Should not have access to this.navHome -> undefined (loads before options API) console.log("4. Calling setup in Container Nav") }, beforeCreate() { // Should not have access to this.navHome -> undefined (loads before options API) console.log("5. Calling beforeCreate in Container Nav") }, created() { // Should have access to this.navHome -> '/' (loads after options API) console.log("6. Calling beforeCreate in Container Nav: ", this.$refs.navHome) }, mounted() { // Should have access to this.navHome -> '/' (loads after options API) console.log("7. Calling beforeCreate in Container Nav: ", this.$refs.navHome) } })</pre> <h1>尝试 1 - 测试</h1> <p>使用 console.logs 运行以下代码会产生以下结果:</p> <pre class="brush:php;toolbar:false;">1. Calling setup in Header 2. Calling beforeCreate in Header: undefined -> Correct 3. Calling Provide in Header 4. Calling setup in Container Nav 5. Calling beforeCreate in Container Nav: undefined -> Correct 6. Calling created in Container Nav: undefined -> Incorrect (should be '/') 7. Calling mounted in Container Nav: undefined -> Incorrect (should be '/') 8. Calling mounted in Header: undefined -> Incorrect (should be '/') 9. Calling created in Header: undefined -> Incorrect (should be '/')</pre> <hr /> <h1>尝试 2 - header.vue(祖父母)</h1> <p>使用与之前相同的代码和选项 API,除了使用 <code>setup</code> 和 <code>provide</code>。</p> <pre class="brush:php;toolbar:false;">import { defineComponent, provide } from 'vue' import parentStore from '@/store' setup() { // 1. Tried this way const navLinkHome = parentStore().getTextualData[0]?.navigation.links.home const navHome = provide('navHome', navLinkHome) // 2. Tried this way const navHome = provide('navHome', parentStore().getTextualData[0]?.navigation.links.home) return { // 1 & 2 navHome // And also this way navHome: provide('navHome', parentStore().getTextualData[0]?.navigation.links.home) } }</pre> <h1>尝试 2 - container-nav.vue(子级)</h1> <pre class="brush:php;toolbar:false;">import { defineComponent, inject } from 'vue' setup() { const navHome = inject('navHome') return { navHome // Tried this too, but same as above just longer navHome: navHome } }</pre> <h1>尝试 2 - 测试</h1> <p>使用 console.logs 运行以下代码会产生以下结果:</p> <pre class="brush:php;toolbar:false;">1. Calling setup in Header 2. Calling beforeCreate in Header: undefined -> Correct 3. Calling setup in Container Nav 4. Calling beforeCreate in Container Nav: undefined -> Correct 5. Calling created in Container Nav: undefined -> Incorrect (should be '/') 6. Calling mounted in Container Nav: undefined -> Incorrect (should be '/') 7. Calling mounted in Header: undefined -> Incorrect (should be '/') 8. Calling created in Header: undefined -> Incorrect (should be '/')</pre> <h2>混乱</h2> <ul> <li><p>首先,我注意到在 <code>header.vue</code> 中使用 <code>provide() {}</code> Options API 时,并尝试引用 <code>navHome</code>。我无法在创建或安装的方法中使用 <code>this.navHome</code> 。我会收到一条错误消息,说它在 <code>CreateComponentPublicInstance</code> 类型上不存在。为了解决这个问题,我改为使用 <code>this.$refs.navHome</code> - 甚至不确定这是否是正确的做法。</p> </li> <li><p>其次,当在 <code>container-nav.vue</code> 组件中使用 <code>inject: [ 'navHome' ]</code> 时,我无法使用 <code>this.navHome</code> 访问它。Again, I can only access it using <code>this.$refs.navHome</code>. </p> </li> </ul> <p>But. </p> <ul> <li>When using Provide in the setup method of <code>header.vue</code> and Inject in the setup method of <code>container-nav.vue</code>, I can use < ;code>this.navHome</code> accesses <code>navHome</code> . Not sure why it does this. </li> </ul><p><br /></p>
P粉377412096P粉377412096462 days ago483

reply all(1)I'll reply

  • P粉121447292

    P粉1214472922023-08-27 00:28:25

    • You need to make sure parentStore().getTextualData[0]?.navigation.links.home has the value "/" as it is not a reactive object when provided by the parent
    • Or you can provide a reactive object like this:
    const navLinkHome = computed(()=> parentStore().getTextualData[0]?.navigation.links.home)
    const navHome = provide('navHome', navLinkHome)
    
    • this.$refs.navHome is the wrong way, this.navHome should work. However, I recommend that you use the Composition API style
    • I'm curious, you already have a pinia store, why do you need to use provide/inject?

    reply
    0
  • Cancelreply