Vue.js `mounted` 中是不是可以使用`async/await`?
Posted
技术标签:
【中文标题】Vue.js `mounted` 中是不是可以使用`async/await`?【英文标题】:Is `async/await` available in Vue.js `mounted`?Vue.js `mounted` 中是否可以使用`async/await`? 【发布时间】:2019-04-30 00:17:32 【问题描述】:我想在mounted()
做这样的事情:
await fetchData1();
await fetchData2UsingData1();
doSomethingUsingData1And2();
所以我想知道这是否有效:
async mounted()
await fetchData1();
await fetchData2UsingData1();
doSomethingUsingData1And2();
,
在我的环境中,它不会引发任何错误,并且似乎运行良好。
但是在这个问题中,生命周期钩子中的async/await
没有实现。
https://github.com/vuejs/vue/issues/7209
我找不到更多信息,但实际上是否可用?
【问题讨论】:
【参考方案1】:它会起作用,因为mounted
钩子在组件已经挂载之后被调用,换句话说,它不会在渲染之前等待承诺解决。唯一的问题是,在 Promise 解决之前,您将拥有一个“空”组件。
如果您需要的是在数据准备好之前不渲染组件,那么您需要在数据中添加一个标志,与 v-if
一起使用,以便在一切准备就绪时渲染组件:
// in your template
<div v-if="dataReady">
// your html code
</div>
// inside your script
data ()
return
dataReady: false,
// other data
,
async mounted()
await fetchData1();
await fetchData2UsingData1();
doSomethingUsingData1And2();
this.dataReady = true;
,
【讨论】:
对于其他使用 axios 来读取 api 数据的人,我可以使用上述解决方案以及 axios 的 promise 方法:async mounted () await axios.get('/api/myGetRequest').then(response => (this.mydata = response)) this.dataReady = true
@Rocky await
为您解决承诺。 axios 提供了一个 async/await 示例。如果你自己处理承诺,那么 async/await 是不必要的。
@None 在我的情况下这不是真的。我的响应时间异常缓慢。也许async/await
模式允许更长的响应时间?我不确定规范,但我保证我必须履行承诺。
@None 我还应该注意,我正在通过 Vue 的 devServer.proxy
对象使用代理服务器并使用 .pathRewrite
重写路径。而且,我的要求是在加载整个页面之前等待数据。对于我最初的评论,我认为此信息超出了问题的范围,但根据您的评论,我认为可能需要注意。
我无法让async
在async data ()
上工作,所以必须使用async mounted ()
,如下所示。谢谢。 +1。【参考方案2】:
编辑:如文档中所述,这是一项实验性功能,目前不应在生产应用程序中使用。
在 vue3 中正确的做法是让你的 setup() 函数像这样异步:
<script>
// MyComponent.vue
export default defineComponent(
/* ... */
async setup()
await fetchData1();
await fetchData2UsingData1();
doSomethingUsingData1And2();
this.dataReady = true;
</script>
然后在父级中使用suspense component 来添加这样的后备:
<template>
<Suspense>
<template #default>
<MyComponent />
</template>
<template #fallback>
Loading...
</template>
</Suspense>
</template>
所以您会在组件加载时看到#fallback 模板,然后在组件准备好时看到组件本身。
【讨论】:
这应该有一个警告,关于悬念是实验性的,不建议用于生产。我会添加上述警告,但编辑队列目前已满。 @AlexisTyler 你说得对,我在答案的顶部添加了一个快速注释。【参考方案3】:只需使用 $nextTick 来调用异步函数。
【讨论】:
$nextTick
是关于 DOM 渲染,async
是关于异步调用函数(简单来说:不阻塞整个应用程序)。所以,这不可能是一般意义上的解决方案。以下是of.docs 的引用:“在下一个 DOM 更新周期后延迟执行回调。在更改一些数据后立即使用它以等待 DOM 更新。”,
如果您这样做,并且感觉它可以工作,那么您可能会很难调试为什么它在以后不再工作。它(几乎)相当于制作一个await sleep(17)
(休眠17ms)。如果组件的加载时间少于 17 毫秒,那就太多了。如果超过 17 毫秒,它将无法工作。而且您实际上无法预测加载需要多少时间,这取决于您的应用程序的复杂性、互联网连接、运行它的计算机的功率、月相...以上是关于Vue.js `mounted` 中是不是可以使用`async/await`?的主要内容,如果未能解决你的问题,请参考以下文章