组件加载时,Vue的Provide和Inject出现未定义的情况
P粉377412096
P粉377412096 2023-08-26 09:34:12
[Vue.js讨论组]
<p><br /></p><h2>情况</h2> <p>我正在尝试使用 Vue 的提供和注入功能的选项 API,以便 <code>header.vue</code> 组件可以向 <code>container-nav.vue</code> 组件提供数据(请参阅组件层次结构)。但是,当注入数据时,它在初始加载时是未定义的。</p> <p><strong>当前组件层次结构:</strong></p> <ul> <li>header.vue &gt; header-nav-menu.vue &gt; 容器-nav.vue</li> </ul> <h1>尝试 1 - header.vue(祖父母)</h1> <p>在此组件中,我从 pinia (storeCommon) 获取 <code>Provide() {}</code> 内的以下字符串 <code>'/'</code>。</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 -&gt; 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 -&gt; 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 -&gt; '/' (loads after options API) console.log("9. Calling beforeCreate in Container Nav: ", this.$refs.navHome) }, mounted() { // Should have access to this.navHome -&gt; '/' (loads after options API) console.log("8. Calling beforeCreate in Container Nav: ", this.$refs.navHome) } })</pre> <h1>尝试 1 - container-nav.vue(子级)</h1> <p>在此组件中,我注入由 <code>header.vue</code> 组件提供的 <code>navHome</code>。</p> <pre class="brush:php;toolbar:false;">import { defineComponent } from 'vue' export default defineComponent({ inject: [ 'navHome' ], setup() { // Should not have access to this.navHome -&gt; undefined (loads before options API) console.log("4. Calling setup in Container Nav") }, beforeCreate() { // Should not have access to this.navHome -&gt; undefined (loads before options API) console.log("5. Calling beforeCreate in Container Nav") }, created() { // Should have access to this.navHome -&gt; '/' (loads after options API) console.log("6. Calling beforeCreate in Container Nav: ", this.$refs.navHome) }, mounted() { // Should have access to this.navHome -&gt; '/' (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 -&gt; Correct 3. Calling Provide in Header 4. Calling setup in Container Nav 5. Calling beforeCreate in Container Nav: undefined -&gt; Correct 6. Calling created in Container Nav: undefined -&gt; Incorrect (should be '/') 7. Calling mounted in Container Nav: undefined -&gt; Incorrect (should be '/') 8. Calling mounted in Header: undefined -&gt; Incorrect (should be '/') 9. Calling created in Header: undefined -&gt; 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 &amp; 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 -&gt; Correct 3. Calling setup in Container Nav 4. Calling beforeCreate in Container Nav: undefined -&gt; Correct 5. Calling created in Container Nav: undefined -&gt; Incorrect (should be '/') 6. Calling mounted in Container Nav: undefined -&gt; Incorrect (should be '/') 7. Calling mounted in Header: undefined -&gt; Incorrect (should be '/') 8. Calling created in Header: undefined -&gt; 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> 访问它。同样,我只能使用 <code>this.$refs.navHome</code> 访问它。</p> </li> </ul> <p>但是。</p> <ul> <li>当在 <code>header.vue</code> 的设置方法中使用 Provide 并在 <code>container-nav.vue</code> 的设置方法中使用 Inject 时,我可以使用 <code>this.navHome</code> 访问 <code>navHome</code> 。不知道为什么这样做。</li> </ul><p><br /></p>
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 商店,为什么还需要使用提供/注入?
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

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