I am trying to use the Options API for the Provide & Inject capabilities of Vue, so that the header.vue
component can provide data to the container-nav.vue
component (see component hierarcy). However, when the data is injected, it is undefined on initial load.
Current Component Hierarchy:
In this component, I am fetching the following string '/'
inside Provide() {}
, from pinia (storeCommon).
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)
}
})
In this component, I am injecting navHome
that was provided by the header.vue
component.
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)
}
})
Running the following code with the console.logs produces the following result:
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 '/')
Using the same code as before & Options API, apart from using the setup
with provide
.
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)
}
}
import { defineComponent, inject } from 'vue'
setup() {
const navHome = inject('navHome')
return {
navHome
// Tried this too, but same as above just longer
navHome: navHome
}
}
Running the following code with the console.logs produces the following result:
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 '/')
First of all, I noticed when using the provide() {}
Options API within header.vue
, and trying to reference navHome
. I could not use this.navHome
inside the created or mounted methods. I would get an error saying that it did not exist on type CreateComponentPublicInstance
. To combat this problem, I instead used this.$refs.navHome
- not even sure if this is the right thing to do.
Secondly, when using inject: [ 'navHome' ]
inside the container-nav.vue
component, I could not access it using this.navHome
. Again, I could only access it using this.$refs.navHome
.
HOWEVER.
header.vue
and Inject inside the setup method of container-nav.vue
, I could access navHome
using this.navHome
. Not sure why it does this.parentStore().getTextualData[0]?.navigation.links.home
has the value "/"
at the time the parent provides it because it is not a reactive objectconst 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 you use the composition API style