【问题标题】:How can I use async/await in the Vue 3.0 setup() function using Typescript如何使用 Typescript 在 Vue 3.0 setup() 函数中使用 async/await
【发布时间】:2021-01-14 22:01:39
【问题描述】:

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

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

没有 async,这段代码运行良好:

// 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() 时,代码有效, 但随后我将无法在 setup 函数中使用 async/await。

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

编辑:

这个问题的答案:why i got blank when use async setup() in Vue3 表明async setup() 确实适用于 JavaScript,所以我希望它也适用于 TypeScript。

【问题讨论】:

  • 要使用async setup(),你需要使用,你可以google并阅读它的工作原理。
  • 谢谢,我会在我再次尝试async setup() 时进行调查。
  • 关于 它只能应用于子组件,因此您不能在具有异步设置的同一组件中使用 ,这意味着 App.vue(顶级组件)必须是同步的,有点烦人,但它就是这样工作的。

标签: typescript vue.js async-await vuejs3 vue-composition-api


【解决方案1】:

尝试使用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,
    };
  },

LIVE DEMO

【讨论】:

  • 这确实有效。但我不想在开始异步调用之前等待组件挂载。
  • @HendrikJan 你可以使用 onBeforeMount 而不是 onMounted
  • @HendrikJan 您甚至可以在 beforeCreate 生命周期挂钩之前开始异步调用,请参阅 here
【解决方案2】:

另一种方法:

 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 一起使用。

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

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

(async () => {

防止这个错误的另一种方法是在函数定义的同一行始终使用分号,以下代码也可以:

;(async () => {

【讨论】:

  • 干净多了!并且注意不要将执行括号放在分组括号内:你会得到一个 TS1128: Declaration or statement expected.
  • 当您创建一个立即调用的函数时,您将线程分成两个并行运行。此答案将始终返回一个空用户,然后对其进行更新。您应该改用 suspense 和异步设置。除非你想要这种更新 UI 的错误体验。
【解决方案3】:

另一种方法是使用承诺链,这样做的好处是代码甚至在 beforeCreate 生命周期钩子之前运行:

import { defineComponent, ref } from 'vue'
import { getData } from './api.js'

export default defineComponent({
  setup() {
    const users = ref([])

    getData().then(({ data }) => (users.value = data))

    return {
      users,
    }
  },
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-01
    • 2019-05-24
    • 2018-01-16
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多