Ionic 视图中的 Vue 悬念

Vue Suspense in Ionic view

我有这样的看法:

<template>
  <ion-page>
    <ion-router-outlet></ion-router-outlet>
    <suspense>
      <template #default>
        {{ pages }}
      </template>
      <template #fallback>
        <div>Loading...</div>
      </template> 
    </suspense>
  </ion-page>
</template>
...
async setup() {
    const storageRef = storage.ref();
    const bookRef = storageRef.child("content/books/bk0000001");
    const pages = await bookRef.listAll();
    console.log({ pages }); // is logged correctly

    return { pages }
}

虽然它似乎可以很好地加载内容,但没有呈现模板,页面仍然是空的,defaultfallback 内容都没有显示。

我做错了什么?

当组件的 setup()async 时,组件必须在组件的父级 中的 <suspense> 内(不是在组件本身中)。

您应该将 {{ pages }} 标记和从 async setup() 获取的数据移动到它自己的组件中:

<!-- AsyncPages.vue -->
<template>
  <ul>
    <li v-for="page in pages" :key="page.id">{{ page.title }}</li>
  </ul>
</template>

<script>
import { defineComponent } from 'vue'

export default defineComponent({
  async setup() {
    const resp = await fetch('https://jsonplaceholder.typicode.com/posts')
    const pages = await resp.json()
    return { pages }
  }
})
</script>

并更新父组件以在 <suspense>:

中使用新组件
<!-- Parent.vue -->
<template>
  <ion-page>
    <ion-router-outlet></ion-router-outlet>
    <suspense>
      <template #default>
        <AsyncPages />
      </template>
      <template #fallback>
        <div>Loading...</div>
      </template>
    </suspense>
  </ion-page>
</template>

<script>
import { defineComponent } from 'vue'
import AsyncPages from '@/components/AsyncPages.vue'

export default defineComponent({
  components: {
    AsyncPages
  }
})
</script>

demo 1

或者,您可以使用 onMounted 异步挂钩将上面的代码重写为非异步 setup()

<!-- Parent.vue -->
<template>
  <ion-page>
    <ion-router-outlet></ion-router-outlet>
    <ul v-if="pages">
      <li v-for="page in pages" :key="page.id">{{ page.title }}</li>
    </ul>
    <div v-else>Loading...</div>
  </ion-page>
</template>

<script>
import { defineComponent, onMounted, ref } from 'vue'

export default defineComponent({
  setup() {
    const pages = ref(null)

    onMounted(async () => {
      const resp = await fetch('https://jsonplaceholder.typicode.com/posts')
      pages.value = await resp.json()
    })

    return { pages }
  }
})
</script>

demo 2