@vue-композиция / Как я могу использовать асинхронные методы в setup()

<script lang="ts">
import { createComponent } from "@vue/composition-api";

import { SplashPage } from "../../lib/vue-viewmodels";

export default createComponent({
  async setup(props, context) {
    await SplashPage.init(2000, context.root.$router, "plan", "login");
  }
});
</script>

ОШИБКА: "setup" должен возвращать "Object" или "Function", получил "Promise"

2 ответа

В setupфункция должна быть синхронной может бытьasyncс помощью Suspense.

Как избежать использования асинхронной настройки (устаревший ответ)

An onMounted крючок можно использовать с async Перезвоните:

import { onMounted } from "@vue/composition-api";

// …
export default createComponent({
  setup(props, context) {
    onMounted(async () => {
      await SplashPage.init(2000, context.root.$router, "plan", "login");
    )};
  }
});

Или всегда можно вызвать асинхронную функцию, не ожидая ее:

SplashPage.init(2000, context.root.$router, "plan", "login")
  .catch(console.log);

В обоих случаях вам необходимо принять во внимание, что компонент будет отображаться до выполнения асинхронной функции. Простой способ не отображать то, что от него зависит, - это использоватьv-if в вашем шаблоне.

У меня есть другое решение, которое работает в моем случае использования. Может быть, это поможет. Это немного похоже на лайфстайл-хук, но без необходимости. Он также не нуждается в <Suspense>тег, который был «излишним» в моем случае использования.

Идея состоит в том, чтобы вернуть значение по умолчанию (в данном случае это пустой массив, но это может быть страница-заставка "Загрузка..."). Затем, после asyncрешил, обновите реактивную опору ( menuItemsмассив здесь, но это может быть фактическое содержимое заставки или html или что-то еще).

Я знаю, что это может не подходить для всех вариантов использования, но это еще один подход, который работает.

Упрощенный код:

      setup () {
  const menuItems = ref([])

  const buildMenuItems = async () => {
     // eg get items from server, return an array of formatted items...
  }
  
  /* setTimeout(async () => {
    menuItems.value = await buildMenuItems()
  }, 0) */ 

  // or..
  ;(async () => {
    menuItems.value = await buildMenuItems()
  })()  

  return {
    menuItems
  } 
}

Я проверил это, заставив buildMenuItems() занять 2 секунды, и все работает нормально.

РЕДАКТИРОВАТЬ : И затем я обнаружил другие способы (даже для не TypeScript): как я могу использовать async/await в функции Vue 3.0 setup() с помощью Typescript

Привет, Мюррей

Другие вопросы по тегам