Subscribe on changes!

<script setup> using await block render

avatar
May 4th 2021

Version

3.0.11

Reproduction link

vue-sfc reproduce link

Steps to reproduce

  • uncomment the async function part
  • the msg will not be rendered

What is expected?

show msg

What is actually happening?

not rendered

image

avatar
May 4th 2021

the component should wrap with <Suspense>? I don't remember need to do that😕 maybe I developed w/ tsx before

avatar
May 4th 2021

As you can see in the "JS" tab of your SFC Playground link, using await at the top level results in an async setup function:

const __sfc__ = {
  expose: [],

  // setup is now `async`
  async setup(__props) {


  
    async function test(){
      return 'hello'
    }
    const msg = await test()


    // this is the inlined render function compiled from the template
    return (_ctx, _cache) => {
      return (_openBlock(), _createBlock("h1", null, _toDisplayString(_unref(msg)), 1 /* TEXT */))
    }
  }
}

Async setup functions can only be used in components nested in a Suspense component.

I'll coordinate with the docs team that this is made more visible in the Guide chapter about the "normal" setup function.

You have different possibilities to work around this:

  1. IIFE:
<script setup>
import { ref } from 'vue'
const msg = ref()
  
async function test(){
  return 'hello'
}

(async () => msg.value = await test())()

</script>
  1. Normal Promise usage with .then()
<script setup>
import { ref } from 'vue'
const msg = ref()
  
async function test(){
  return 'hello'
}

test().then((result) => msg.value = result)

</script>