我的 Vue.js 应用程序有以下情况:
data() {
return {
data: []
}
},
async created() {
console.log('before async call')
try {
// async call ...
console.log('after async call')
this.data = // data from api call
} catch (err) {
// handle err
}
},
mounted() {
console.log('mounted')
init(this.data)
}
Run Code Online (Sandbox Code Playgroud)
当我运行代码时,我得到:
before async call
mounted
after async call
Run Code Online (Sandbox Code Playgroud)
因此,init 方法(mounted 中的类构造函数)会使用空数组而不是来自 API 调用的数据进行调用。我想要的是同步执行事物,并且在数据可用之前不执行安装。我知道上面的问题是当包含异步代码时Vue如何执行生命周期,但是如何解决这样的问题呢?
asyncVue 中的生命周期是一种具有误导性的语法。
每个 Vue 生命周期只是一个触发器,用于运行您在特定时间放入的任何代码。
但 Vue 不会等待 Promise 解决并保留其他所有内容(与组件的生命周期相关),直到它发生为止。实际上,您所做的就是延迟放置在生命周期中的代码的执行,直到某些承诺得到解决。
为了让您更好地理解正在发生的事情,以下语法是等效的:
async created() {
const data = await fetchSomeData();
// rest of code depending on `data`
}
Run Code Online (Sandbox Code Playgroud)
等价的:
created() {
fetchSomeData().then(data => {
// rest of code depending on `data`
});
}
Run Code Online (Sandbox Code Playgroud)
由于async生命周期是一种误导性的语法,因此在大型团队开发的应用程序中通常不鼓励使用它,而倾向于使用该.then()语法。这是为了避免代码实际运行时因误解而产生的小错误。例如,如果新开发人员将一些代码放入钩子中async(没有仔细查看钩子中的其余代码),则代码可能会比预期运行得晚,除非放置在任何await.
要修复您想要修复的任何错误,只需将无法渲染的内容包装起来,直到实际data解析为if(内部组件)或v-if(内部模板)。
典型用法示例:
computed: {
someComputed() {
if (this.data.length) {
// returned when data has length
return something
}
// returned when data has no length
return somethingElse
}
}
Run Code Online (Sandbox Code Playgroud)
或者:
<div v-if="data.length">
<!-- markup depending on actual data... -->
</div>
<div v-else>
loading...
</div>
Run Code Online (Sandbox Code Playgroud)
注意:computed上面的内容将自动对 的长度变化做出反应data(不需要 a watch),因为computed每当属性的内部反应引用改变值时,属性就会重新运行。正如您所期望的,它们会根据它们重新计算/重新渲染任何内容。对于 也是如此<v-if>。在内部,它们都使用所谓的 Vue 的“注入和反应性”。