【问题标题】:Unable to mark Vue setup function as async无法将 Vue 设置功能标记为异步
【发布时间】:2022-01-24 15:36:30
【问题描述】:

我有一个使用组合 API 的 Vue3 应用程序,并希望在 setup 函数内异步获取数据。

对我有用的方法:


使用承诺

    <template>
      <div>{{ result }}</div>
    </template>
    
    <script lang="ts">
    import { defineComponent, ref } from "vue";
    
    export default defineComponent({
      setup() {
        const result = ref();
    
        fetch("https://api.publicapis.org/entries")
          .then((response: Response) => response.json())
          .then((jsonResponse: any) => {
            result.value = jsonResponse;
          });
    
        return { result };
      },
    });
    </script>

使用 onMounted 挂钩

    <template>
      <div>
        {{ result }}
      </div>
    </template>
    
    <script lang="ts">
    import { defineComponent, ref, onMounted } from "vue";
    
    export default defineComponent({
      setup() {
        const result = ref();
    
        onMounted(async () => {
          const response = await fetch("https://api.publicapis.org/entries");
          result.value = await response.json();
        });
    
        return { result };
      },
    });
    </script>

但我不能像这样直接使用 async/await

    <template>
      <Suspense>
        <template #default>
          {{ result }}
        </template>
        <template #fallback> Loading... </template>
      </Suspense>
    </template>
    
    <script lang="ts">
    import { defineComponent, ref } from "vue";
    
    export default defineComponent({
      async setup() {
        const result = ref();
    
        const response = await fetch("https://api.publicapis.org/entries");
        result.value = await response.json();
    
        return { result };
      },
    });
    </script>

基于这个问题

@vue-composition / How can I use asynchronous methods in setup()

还有这篇链接的文章

https://vueschool.io/articles/vuejs-tutorials/suspense-new-feature-in-vue-3/

它应该可以工作。

发布的组件只是 Vue 路由器渲染的默认 Home.vue 组件。所以在 App.vue 中,我使用标签 &lt;router-view /&gt; 并使用主路由加载应用程序。

如何将setup 标记为async

【问题讨论】:

  • 您没有展示该组件的使用方式。异步设置应专门用于悬念。
  • 等一下,我会更新我的问题
  • @EstusFlask 它只是 CLI 生成的基本应用程序骨架中的 Home.vue 视图组件

标签: vue.js vuejs3 vue-suspense


【解决方案1】:

首先请小心,因为Suspense 仍是实验性功能,随时可能更改...

为了async setup 工作,组件本身 必须在&lt;suspense&gt; 内 ....您的组件不在&lt;suspense&gt; 内 - 它包含 &lt;suspense&gt; 组件(当然,在创建组件之前它不能工作,并且只有在你的 async setup 解决之后才会发生)。您必须将 &lt;suspense&gt; 放置为 &lt;router-view&gt; - see the docs 的子级

这是working demo(如果您首先看到import declarations may only appear at top level of a module,只需使用重新加载图标重新加载右侧窗格 - 似乎矩阵中的一些故障)

// App.vue
<router-view v-slot="{ Component }">
  <suspense timeout="0">
    <template #default>
      <component :is="Component"></component>
    </template>
    <template #fallback>
      <div>Loading...</div>
    </template>
  </suspense>
</router-view>
// Home.vue
<template>
  <div class="home">
    <pre>{{ result }}</pre>
  </div>
</template>

<script>
import { defineComponent, ref } from "vue";

export default defineComponent({
  async setup() {
    const result = ref();

    const response = await fetch("https://api.publicapis.org/entries");
    result.value = await response.json();

    return { result };
  },
});
</script>

注意timeout="0" on suspense - it seems 有一个 timeout 用于切换到“加载”状态(可能是为了避免在异步组件足够快地解析时出现过多的屏幕闪烁)

可以指定 timeout 属性 - 如果挂起的树仍然挂起超过超时阈值,则活动树将被卸载并被备用树替换。

我现在无法找到 timeout 的默认值。随意调整它以满足您自己的需要...

【讨论】:

  • 好一个超时,没看到。我希望默认情况下没有超时
  • 啊……我傻了……谢谢你的解释:)
猜你喜欢
  • 2021-08-05
  • 1970-01-01
  • 2021-06-25
  • 2017-06-22
  • 1970-01-01
  • 1970-01-01
  • 2020-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多