Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why did I get blank (empty) content when I used async setup() in Vue.js 3?

Problem

I use async setup() in Vue.js 3, but I got my HTML content to disappear. My component template did not insert to HTML, but when I remove the async and await prefix, my HTML content comes back. How can I fix this?

async setup () {
    const data = ref(null)
    try {
        const res = await fetch('api')
        data.value = res.json()
    }
    catch (e) {
        console.error(e)
    }
    return {
        data
    }
}

I've tried

  1. I checked fetch, and it returned the correct response
  2. I've tried <Suspense> tag, but still the same problem
like image 826
g6165310 Avatar asked Sep 22 '20 12:09

g6165310


People also ask

How do I use async await with Vue components?

To use async and await in Vue. js, we can add async and await in our component methods and hooks. to make the created hook an async method. We use await to wait for the getA method to finish before running the rest of the code.

What are Vue async components?

These components can be tooltips, popovers, modals, etc, and can be used as async components. Let's see how to build and lazy load these async components in Vue.

What is script setup in Vue?

<script setup> <script setup> is a compile-time syntactic sugar for using Composition API inside Single-File Components (SFCs). It is the recommended syntax if you are using both SFCs and Composition API. It provides a number of advantages over the normal <script> syntax: More succinct code with less boilerplate.

What is $El in Vue?

The $el option in Vue provides Vue with an existing HTML element to mount the Vue instance generated using the new keyword. this. $el. querySelector is used to access HTML elements and modify the element's properties.


2 Answers

Your component's async setup() looks fine other than the missing await res.json(), which still wouldn't cause the problem you're seeing. I suspect your usage of <Suspense> is incorrect.

To use async setup() in a component, the parent component must use that component in a <Suspense> tag:

<!-- Parent.vue -->
<template>
 <Suspense>
   <MyAsyncComponent />
 </Suspense>
</template>

You could also use the default and fallback slots of <Suspense> to show a loading indicator while waiting for the child component's setup to resolve:

<!-- Parent.vue -->
<template>
 <Suspense>
   <template #default>
     <MyAsyncComponent />
   </template>
   <template #fallback>
     <span>Loading...</span>
   </template>
 </Suspense>
</template>

demo

like image 98
tony19 Avatar answered Oct 18 '22 22:10

tony19


File parent.vue

<template>
  <!-- parent add <suspense> -->
  <suspense>
    <child />
  </suspense>
</template>

<script>
import Child from './child.vue'

export default {
  components: {
    child
  },
  setup() {
    return {}
  }
}
</script>

File child.vue

<template>
  <div>child</div>
</template>

<script>
export default {
  async setup() {
    return {}
  }
}
</script>

For child.vue, use async setup.... For parent.vue, you need to add <suspense> to child.vue.

like image 2
Sinosaurus Avatar answered Oct 18 '22 20:10

Sinosaurus