Vue Options API中Provide&Inject初始加载数据为undefined问题
场景说明
尝试用Vue的Options API实现Provide & Inject功能,让header.vue组件向container-nav.vue组件传递数据,组件层级如下:
- header.vue > header-nav-menu.vue > container-nav.vue
但初始加载时注入的数据为undefined。
尝试方案1
header.vue(祖先组件)
通过Pinia(storeCommon)在provide()中获取字符串'/',代码如下:
import { defineComponent } from 'vue' import parentStore from '@/store' export default defineComponent({ setup() { // 此时无法访问this.navHome -> undefined(先于Options API加载) console.log("1. Calling setup in Header") const storeCommon = parentStore() return { storeCommon } }, beforeCreate() { // 此时无法访问this.navHome -> undefined(先于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() { // 此时应能访问this.navHome -> '/'(晚于Options API加载) console.log("9. Calling beforeCreate in Container Nav: ", this.$refs.navHome) }, mounted() { // 此时应能访问this.navHome -> '/'(晚于Options API加载) console.log("8. Calling beforeCreate in Container Nav: ", this.$refs.navHome) } })
container-nav.vue(子组件)
注入header.vue提供的navHome,代码如下:
import { defineComponent } from 'vue' export default defineComponent({ inject: [ 'navHome' ], setup() { // 此时无法访问this.navHome -> undefined(先于Options API加载) console.log("4. Calling setup in Container Nav") }, beforeCreate() { // 此时无法访问this.navHome -> undefined(先于Options API加载) console.log("5. Calling beforeCreate in Container Nav") }, created() { // 此时应能访问this.navHome -> '/'(晚于Options API加载) console.log("6. Calling beforeCreate in Container Nav: ", this.$refs.navHome) }, mounted() { // 此时应能访问this.navHome -> '/'(晚于Options API加载) console.log("7. Calling beforeCreate in Container Nav: ", this.$refs.navHome) } })
测试结果
运行代码后控制台输出:
1. Calling setup in Header 2. Calling beforeCreate in Header: undefined -> 符合预期 3. Calling Provide in Header 4. Calling setup in Container Nav 5. Calling beforeCreate in Container Nav: undefined -> 符合预期 6. Calling created in Container Nav: undefined -> 不符合预期(应为'/') 7. Calling mounted in Container Nav: undefined -> 不符合预期(应为'/') 8. Calling mounted in Header: undefined -> 不符合预期(应为'/') 9. Calling created in Header: undefined -> 不符合预期(应为'/')
尝试方案2
header.vue(祖先组件)
保留原有Options API代码,在setup中使用provide,代码如下:
import { defineComponent, provide } from 'vue' import parentStore from '@/store' setup() { // 方式1 const navLinkHome = parentStore().getTextualData[0]?.navigation.links.home const navHome = provide('navHome', navLinkHome) // 方式2 const navHome = provide('navHome', parentStore().getTextualData[0]?.navigation.links.home) return { // 对应方式1和2 navHome // 还尝试过这种写法 navHome: provide('navHome', parentStore().getTextualData[0]?.navigation.links.home) } }
container-nav.vue(子组件)
在setup中使用inject,代码如下:
import { defineComponent, inject } from 'vue' setup() { const navHome = inject('navHome') return { navHome // 也尝试过这种写法,结果一致 navHome: navHome } }
测试结果
运行代码后控制台输出:
1. Calling setup in Header 2. Calling beforeCreate in Header: undefined -> 符合预期 3. Calling setup in Container Nav 4. Calling beforeCreate in Container Nav: undefined -> 符合预期 5. Calling created in Container Nav: undefined -> 不符合预期(应为'/') 6. Calling mounted in Container Nav: undefined -> 不符合预期(应为'/') 7. Calling mounted in Header: undefined -> 不符合预期(应为'/') 8. Calling created in Header: undefined -> 不符合预期(应为'/')
疑问点
- 在
header.vue中使用Options API的provide() {}时,尝试在created或mounted中引用navHome,用this.navHome会报错,提示该属性不存在于CreateComponentPublicInstance类型中,只能改用this.$refs.navHome,不确定是否正确。 - 在
container-nav.vue中使用inject: [ 'navHome' ]时,同样无法通过this.navHome访问,只能用this.$refs.navHome。
例外情况:
- 当在
header.vue的setup中使用Provide,在container-nav.vue的setup中使用Inject时,可以通过this.navHome访问数据,不清楚原因。
内容的提问来源于stack exchange,提问作者Dylan
相关产品推荐
相关产品推荐

