Vue <script setup> 顶级等待导致模板不渲染

olv*_*age 26 javascript promise vue.js

我在 Vue 3 中使用新语法,我真的很喜欢它的想法,但是一旦我尝试使用顶级等待,我就开始遇到一些问题。

这是我的代码:

<template>
  <div class="inventory">
    <a class="btn btn-primary">Test button</a>
      <table class="table">
        <thead>
          <tr>Name</tr>
          <tr>Description</tr>
        </thead>
        <tbody>
          <tr v-for="(item, key) in inventory" :key="key">
            <td>{{ item.name }}</td>
            <td>{{ item.description }}</td>
          </tr>
        </tbody>
      </table>
  </div>
</template>

<script setup lang="ts">
import { apiGetInventory, GetInventoryResponse } from '@/module/inventory/common/api/getInventory'

const inventory: GetInventoryResponse = await apiGetInventory()
</script>
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,它并没有那么复杂, apiGetInventory 只是一个 axios 调用,所以我不会费心去讨论它。问题是,如果我有这个顶级等待,我的模板将不再呈现,它只是浏览器中的一个空白页面。如果我删除这两行代码,它就可以正常工作。而且这个承诺似乎运行得很好,如果我在它下面放置一个 console.log(inventory) ,我会得到一个包含所有精美对象的数组。

有人知道这里出了什么问题吗?

tau*_*uzN 20

顶级await必须与Suspense(处于实验阶段)结合使用。

你应该能够在onBeforeMount. 不那么优雅;而是一个固溶方案。像这样的事情:

<script setup lang="ts">
import { apiGetInventory, GetInventoryResponse } from '@/module/inventory/common/api/getInventory';
import { ref, onBeforeMount } from 'vue';

const inventory = ref<GetInventoryResponse>()

onBeforeMount( async () => {
    inventory.value = await apiGetInventory()
})
</script>
Run Code Online (Sandbox Code Playgroud)


mrt*_*rts 5

使用onBeforeMount固然很好,但还有其他一些选择。

async@skirtle 在 Vue Discord 聊天中建议在lambda 或函数(可能作为 IIFE)内进行初始化:

<script setup lang="ts">
let inventory: GetInventoryResponse
const loadData = async () => inventory = apiGetInventory()
loadData()
</script>
Run Code Online (Sandbox Code Playgroud)

@wenfang-du 在How can I use async/await in the Vue 3.0 setup() function using Typescript to use Promise Chaining中建议:

<script setup lang="ts">
let inventory: GetInventoryResponse 
apiGetInventory().then(d: GetInventoryResponse => inventory = d)
</script>
Run Code Online (Sandbox Code Playgroud)

这样做的好处是代码在beforeMount生命周期挂钩之前运行。

您还需要在这两种情况下酌情处理错误。