【问题标题】:Vue 3 setup reactive fetch with async jsonVue 3 使用异步 json 设置响应式获取
【发布时间】:2021-02-07 08:46:38
【问题描述】:

我已经安装了 Vue 3,并希望使用从 JSON API 获取的数据来填充反应式对象。

我的组件如下所示。我没有收到任何错误,但我也没有得到任何结果。

<template>
  <div>
    {{ state.test.total }}
  </div>
</template>

<script>
import { reactive } from "vue";

export default {
  setup() {
    const state = reactive({
      test: null,
    });

    state.test = async () => {
      return await fetch("https://api.npms.io/v2/search?q=vue");
    };

    return {
      state,
    };
  },
};
</script>

我希望在屏幕上显示一个数字,因为那是 JSON 文件中 total 中的内容。

开启state.test

如果我只输出state.test,我会得到下面的输出。

function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } 函数_throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }

知道如何绕过它吗?

【问题讨论】:

    标签: javascript vue.js async-await fetch vuejs3


    【解决方案1】:

    当你这样做时:

    a = async function test() {
    }
    

    您正在为您的状态分配一个功能。但如果你这样做了

    a = (async function test() {
    })();
    

    您仍在为a 分配一个承诺,而不是一个值。如果你想分配一个值,你需要解决这个承诺:

    funcResult = await a;
    

    您的 setup 函数不适合在组件的生命周期内执行代码。您可以将 setup 函数视为组件的工厂。因此 setup 函数应该始终是同步的(没有 async 关键字),否则 vue 在 setup 解析时将不知道它应该显示什么。幸运的是,您可以在组合 API 中使用钩子:

    import { onMounted, reactive } from "vue";
    
    export default {
      setup() {
        const state = reactive({
          test: null,
        });
    
    
        onMounted(async () => {
          const response = await fetch("https://api.npms.io/v2/search?q=vue");
          state.test = await response.json();
        });
    
    
        return {
          state,
        };
      },
    };
    

    编辑

    考虑到@boussadjra-brahim 的回答,您实际上可以定义异步设置函数,但前提是您使用&lt;Suspense&gt; 包装您的组件。所以你可以选择这个或那个变体。

    【讨论】:

    • 经过一些修改后工作正常。你在 onMounted 结束时切换了)};。我忘了在提取的末尾添加.then((response) =&gt; response.json());。非常感谢!
    • +1 "您可以将 setup 函数视为组件的工厂。因此 setup 函数应该始终是同步的",有用的建议。
    • @matt 你们如何看待下面的async setup() 解决方案?这是好的还是不好的做法?
    • @JensTörnell 这种情况没有必要。 setup 函数不需要等待。您可以做一些返回承诺的事情并使用.then() 来填充反应变量。对于加载指示器等更高级的内容,您可以使用Suspense 组件。
    • @JensTörnell 我已经发布了答案。
    【解决方案2】:

    您应该将async 添加到设置选项,将await 添加到获取功能,并通过Suspense 组件包装您的模板内容:

    <template>
       <Suspense>
        <div>
          {{ state.test.total }}
        </div>
      </Suspense>
    </template>
    
    <script>
    import { reactive } from "vue";
    export default {
      async setup() {
        const state = reactive({
          test: null,
        });
    
        try{
          state.test =  await fetch("https://api.npms.io/v2/search?q=vue");
         } catch (err) {
           console.error(err)
       }
    
        return {
          state,
        };
      },
    };
    

    【讨论】:

      【解决方案3】:

      我认为最好不要wait

      示例:

      <template>
          <div>
              {{ state }}
          </div>
      </template>
      
      
      <script>
      import { ref } from 'vue';
      
      export default {
          setup() {
              const state = ref({});
      
              fetch('https://api.npms.io/v2/search?q=vue')
                  .then(response => response.json())
                  .then(data => state.value = data);
      
              return { state };
          },
      };
      </script>
      

      【讨论】:

      • 这个用例接受了三个建议的解决方案,例如,如果组件是像表格或列表这样的数据显示,当我们可以添加加载指示器然后显示数据时,我的解决方案可能很有用,但它会如果组件包含另一个依赖逻辑,那就不好了
      • @BoussadjraBrahim 是的,我想Suspense 对此很有用。我没有足够的经验来知道组合函数是否应该是异步的。
      • 感谢您的链接,它们应该是异步的,并且负责在网格中获取和显示数据的独特逻辑,让我们举一个可能包含搜索输入、网格和分页组件,悬念应该只包裹可以异步加载的部分,即网格。
      猜你喜欢
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      • 2022-01-16
      • 2021-11-04
      • 2014-06-29
      • 2018-12-03
      • 2017-10-06
      • 2019-05-25
      相关资源
      最近更新 更多