【问题标题】:How Do I Share Async API Data across Components in Vue 3?如何在 Vue 3 中跨组件共享异步 API 数据?
【发布时间】:2021-08-31 18:30:39
【问题描述】:

我有一个顶级组件,它定期从 API 获取数据。我想发出一个 API 请求并将我的应用程序的所有数据集中在一个地方,以减少对 API 服务器的请求数量。 (仅供参考,我的项目看起来正在使用 Typescript,但我还没有。)

在我的顶级组件中一切正常:

//Parent

<script lang="ts">
import { defineComponent, ref, provide, inject, onMounted } from 'vue'
import getData from '@/data.ts'
  
export default defineComponent({
  setup(){
    const workspaces = ref([])
    
    onMounted(async () => {
      let api = inject('api') //global var from main.ts
      
      let data = await getData(api) //API request inside data.ts
      
      console.log(data.workspaces) //<-- data looks good here
      workspaces.value = data.workspaces
      
      //Trying to share workspaces with other components
      provide('workspaces', data.workspaces)
    })
    return {
      workspaces
    }
  }
})  
</script>

<template>
  {{ workspaces}} <!-- workspaces render fine here -->
</template>

但是我的孩子不能通过inject使用provide数据:

//Child

<script lang="ts">
import { defineComponent, inject, onMounted, ref } from 'vue'

export default defineComponent({
  setup(){
    let workspaces = ref([])
    
    onMounted(async () => {
      workspaces.value = await inject('workspaces') //<-- just a guess; doesn't work
    })
    
    return{
      workspaces
    }
  }
})
</script>

<template>
  {{ workspaces }} <!-- nothing here -->
</template>

我对问题的原因做了几个假设:

  1. Child 组件在父级的 async 内容完成之前加载,因此为空。
  2. 我可能无法在 async 这样的场景中使用 project/inject

那么,如何在我的应用程序的组件之间共享来自 API 的 async 数据?我唯一的选择是回到老派props 并手动传递数据吗?

【问题讨论】:

  • 您可以创建类似于本地商店的东西。例如,带有 fetch 方法的自定义 js 文件,这也是原始源所在的位置。然后你可以import所有组件中的源数据。这可以想象吗?
  • 在我们的工作场所,Nuxt.js 通过 [fetch] (nuxtjs.org/docs/2.x/features/data-fetching) hook 解决了这个问题
  • 为什么不只是有一个 Vuex 存储并在存储内的 action 中获取数据,然后 commit 你的 mutation 设置一块 state?然后在您的组件中只需 ...mapState({apiData: (store) =&gt; store.someStore.apiData }) 并获取您需要的任何数据?
  • Vuex 可能是我最终的目标,但我一直觉得它令人困惑。我希望通过新的 Vue 组件 API 来避免它。 ??????

标签: vue.js vue-component vuejs3 vue-composition-api


【解决方案1】:

provide/inject 被滥用并受制于竞争条件。组合 API 通常应该用于组件初始化(setup,在任何await 之前),而不是在onMounted 中。即使没有这样的限制,父组件中的onMounted 会在子组件中运行,并且在挂载子组件时无法提供值。

refs 的目的是提供对以后可以更改的值的引用,因此它可以通过引用传递并保持反应性,当前未使用此属性。

它应该在父组件中:

  setup(){
    const workspaces = ref([])
    provide('workspaces', workspaces)
    let api = inject('api')

    onMounted(async () => {
      let data = await getData(api)
      workspaces.value = data.workspaces
    })
    return { workspaces }

在子组件中:

  setup(){
    let workspaces = inject('workspaces')
    return { workspaces }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 2018-05-15
    • 2016-07-01
    • 2018-06-29
    • 2020-08-08
    • 2016-04-27
    相关资源
    最近更新 更多