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>