Vue3模板表达式中能否使用异步函数?求解决方案
Vue3模板中异步函数渲染问题的解决办法
模板表达式中直接调用异步函数会返回Promise对象,Vue无法自动解析Promise的结果,因此会渲染出[object Promise]。以下是几种可行的解决方式:
提前在组件逻辑中获取异步结果
在setup或<script setup>中调用异步函数,将结果存入响应式变量,模板直接引用该变量:<script setup> import { ref, onMounted } from 'vue' const userName = ref('') async function getNameAsync() { // 模拟异步请求逻辑 return new Promise(resolve => setTimeout(() => resolve('Alice'), 1000)) } onMounted(async () => { userName.value = await getNameAsync() }) </script> <template> <p v-if="userName">Hi {{ userName }}</p> <p v-else>Loading...</p> </template>使用
<Suspense>组件处理异步组件
将异步逻辑直接写在组件的setup中(让setup返回Promise),然后用<Suspense>包裹组件,它会自动处理加载状态和结果渲染:<!-- 父组件 --> <template> <Suspense> <AsyncUser /> <template #fallback> <p>Loading...</p> </template> </Suspense> </template> <!-- AsyncUser子组件 --> <script setup> async function getNameAsync() { return new Promise(resolve => setTimeout(() => resolve('Bob'), 1000)) } const userName = await getNameAsync() </script> <template> <p>Hi {{ userName }}</p> </template>封装通用异步渲染组件
可以编写一个复用组件来处理Promise的解析和状态展示:<!-- AsyncRenderer.vue --> <script setup> import { ref, watchEffect } from 'vue' const props = defineProps({ promise: Function, }) const result = ref(null) const loading = ref(true) watchEffect(async () => { loading.value = true try { result.value = await props.promise() } catch { result.value = '获取数据失败' } finally { loading.value = false } }) </script> <template> <slot v-if="!loading" :result="result"></slot> <slot v-else name="loading"></slot> </template>使用示例:
<script setup> import AsyncRenderer from './AsyncRenderer.vue' async function getNameAsync() { return new Promise(resolve => setTimeout(() => resolve('Charlie'), 1000)) } </script> <template> <AsyncRenderer :promise="getNameAsync"> <template #default="{ result }"> <p>Hi {{ result }}</p> </template> <template #loading> <p>Loading...</p> </template> </AsyncRenderer> </template>
内容的提问来源于stack exchange,提问作者Steve Bennett
相关产品推荐
相关产品推荐

