组件加载时,Vue的Provide和Inject出现未定义的情况
P粉377412096
P粉377412096 2023-08-26 09:34:12
[Vue.js讨论组]


情况

我正在尝试使用 Vue 的提供和注入功能的选项 API,以便 header.vue 组件可以向 container-nav.vue 组件提供数据(请参阅组件层次结构)。但是,当注入数据时,它在初始加载时是未定义的。

当前组件层次结构:

  • header.vue > header-nav-menu.vue > 容器-nav.vue

尝试 1 - header.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 - container-nav.vue(子级)

在此组件中,我注入由 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 - header.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 - container-nav.vue(子级)

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 。不知道为什么这样做。


P粉377412096
P粉377412096

全部回复(1)
P粉121447292
  • 您需要确保 parentStore().getTextualData[0]?.navigation.links.home 在父级提供时具有值 "/"因为它不是一个响应式对象
  • 或者您可以提供这样的响应式对象:
const navLinkHome = computed(()=> parentStore().getTextualData[0]?.navigation.links.home)
const navHome = provide('navHome', navLinkHome)
  • this.$refs.navHome 是错误的方式,this.navHome 应该可以工作。不过,我建议您使用组合 API 样式
  • 我很好奇,您已经有了 pinia 商店,为什么还需要使用提供/注入?
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号