Vue在组件加载时提供和注入未定义

zaq34kh6  于 2022-11-25  发布在  Vue.js
关注(0)|答案(1)|浏览(136)

情况
我尝试使用Options API来实现Vue的Provide & Inject功能,这样header.vue组件就可以向container-nav.vue组件提供数据(参见组件层次结构)。但是,当数据被注入时,它在初始加载时是未定义的。

当前组件层次结构:

  • 标题导航菜单〉容器导航菜单

尝试1 -标题.vue(祖父级)

在这个组件中,我从pinia(storeCommon)中获取Provide() {}内的字符串'/'

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

尝试1 -容器导航值(子项)

在这个组件中,我注入了header.vue组件提供的navHome

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

尝试1 -测试

使用console.logs运行以下代码将产生以下结果:

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 '/')

尝试2 -标题.vue(祖父级)

使用与之前相同的代码和选项API,除了使用setupprovide

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

尝试2 -容器导航值(子项)

import { defineComponent, inject } from 'vue'

setup() {
    const navHome = inject('navHome')

    return {
        navHome

        // Tried this too, but same as above just longer
        navHome: navHome
    }
}

尝试2 -测试

使用console.logs运行以下代码将产生以下结果:

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 '/')

困惑

  • 首先,我注意到当在header.vue中使用provide() {} Options API并试图引用navHome时,我无法在创建或挂载的方法中使用this.navHome。我会收到一个错误消息,说它不存在于CreateComponentPublicInstance类型中。为了解决这个问题,我使用了this.$refs.navHome-甚至不确定这样做是否正确。
  • 其次,当在container-nav.vue组件中使用inject: [ 'navHome' ]时,我无法使用this.navHome访问它,同样,我只能使用this.$refs.navHome访问它。

不过,我不知道。

  • 当在header.vue的设置方法中使用Provide和在container-nav.vue的设置方法中使用Inject时,我可以使用this.navHome访问navHome。不知道为什么这样做。
dtcbnfnu

dtcbnfnu1#

  • 您需要确保parentStore().getTextualData[0]?.navigation.links.home在父对象提供它时具有"/"的值,因为它不是React对象
  • 或者,您可以提供一个React对象,如下所示:
const navLinkHome = computed(()=> parentStore().getTextualData[0]?.navigation.links.home)
const navHome = provide('navHome', navLinkHome)
  • this.$refs.navHome是错误的方式,this.navHome应该可以工作。
  • 我很好奇,你已经有了pinia商店,为什么还需要使用provide/inject呢?

相关问题