如何使用 Typescript 在 Vue 3.0 setup() 函数中使用 async/await

新手上路,请多包涵

(这个问题已经回答了 JavaScript,见下文,但这个问题是特定于 TypeScript 的,它的行为不同)

我正在尝试使用打字稿在 Vue3.0 中使用异步功能。

如果没有 异步,这段代码效果很好:

 // file: components/HelloWorld.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script lang="ts">
import {defineComponent} from 'vue'

export default defineComponent({
  name: 'HelloWorld',
  props: {
    msg: String,
  },
  async setup() { // <-- this works without 'async'
    const test = 'test'

    // await doSomethingAsynchronous()

    return {
      test,
    }
  },
})
</script>

使用 async setup() 组件“HelloWorld”从页面中消失,Firefox 控制台告诉我

"Uncaught (in promise) TypeError: node is null (runtime-dom.esm-bundler.js)"

当我将 async setup() 更改为 setup() 时,代码可以工作,但是我将无法在设置函数中使用 async/await。

所以我的问题是:如何使用 Typescript 在 setup() 函数中使用 async/await?

编辑:

这个问题的答案: 为什么我在 Vue3 中使用 async setup() 时出现空白,这 表明 async setup() 确实适用于 JavaScript,所以我希望它也适用于 TypeScript。

原文由 Hendrik Jan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.9k
2 个回答

尝试使用 onMounted 挂钩来操作异步调用:

  setup() {
    const users = ref([]);
    onMounted(async () => {
      const res = await axios.get("https://jsonplaceholder.typicode.com/users");
      users.value = res.data;
      console.log(res);
    });

    return {
      users,
    };
  },

现场演示

最好的方法 是在子组件中使用 async setup 并在父组件中用 Suspense 组件包装该组件:

用户列表.vue

 <script  lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
    async setup() {
        //get users from jsonplacerholder using await fetch api
        const users = await fetch("https://jsonplaceholder.typicode.com/users").then(res => res.json());

        return {
            users
        }
    }
})
</script>
<template>
    <div>
        <!-- list users -->
        <ul>
            <li v-for="user in users">{{ user.name }}</li>
        </ul>
    </div>
</template>

父组件

 <script lang="ts">

import UserList from "../components/tmp/UserList.vue";
...
</script>

   <div>
            <!-- Suspense component  to show users  -->
            <Suspense>
                <template #fallback>
                    <div>loading</div>
                </template>

                <UserList />
            </Suspense>
        </div>

原文由 Boussadjra Brahim 发布,翻译遵循 CC BY-SA 4.0 许可协议

另一种方法:

  const users = ref([]);

 (async () => {
   const res = await axios.get("https://jsonplaceholder.typicode.com/users");
   users.value = res.data;
   console.log(res);
 })()

 return {
   users,
 }

而且您不必等待它挂载,这类似于将 created() 与选项 API 一起使用。

注意:不要忘记总是有一个分号“;”在 function 语句之前,否则,JavaScript 会认为前面的语句应该返回一个函数,例如下面的代码会导致错误“ref([]) is not a function”:

 const users = ref([]) // No semicolon here

(async () => {

防止此错误的另一种方法是始终将分号放在函数定义的同一行,以下代码也有效:

 ;(async () => {

原文由 gustavodacrvi 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏