1.12 数据获取
1.12.1 概述
当路由被激活时,我们往往需要从服务器获取数据,以便能够正确地选渲染组件。数据获取的方式有两种,具体使用哪一种取决于应用场景和用户体验。
导航后获取
首先进行导航,然后在导航进入的组建的生命周期钩子中获取数据。在获取数据时显示加载状态。
导航前获取
在 beforeRouteEnter 中获取数据,数据获取后再进行导航;
1.12.2 导航后获取
当你使用这种方式时,我们会马上导航和渲染组件,然后在组件的 created 钩子中获取数据。这让我们有机会在数据获取期间展示一个 loading 状态,还可以在不同视图间展示不同的 loading 状态。
假设我们有一个
Post
组件,需要基于 $route.params.id
获取文章数据
页面内容
<template>
<div class="post">
<div v-if="loading" class="loading">Loading...</div>
<div v-if="error" class="error">{{ error }}</div>
<div v-if="post" class="content">
<h2>{{ post.title }}</h2>
<p>{{ post.body }}</p>
</div>
</div>
</template>
获取数据的逻辑
export default {
data() {
return {
loading: false,
post: null,
error: null,
}
},
created() {
// watch 路由的参数,以便再次获取数据
this.$watch(
() => this.$route.params,
() => {
this.fetchData()
},
// 组件创建完后获取数据,
// 此时 data 已经被 observed 了
{ immediate: true }
)
},
methods: {
fetchData() {
this.error = this.post = null
this.loading = true
// replace `getPost` with your data fetching util / API wrapper
// 用你的数据获取 util 或 API 替换 `getPost`
getPost(this.$route.params.id, (err, post) => {
this.loading = false
if (err) {
this.error = err.toString()
} else {
this.post = post
}
})
},
},
}
1.12.3 导航前获取
通过这种方式,我们在导航转入新的路由前获取数据。我们可以在接下来的组件的
beforeRouteEnter
守卫中获取数据,仅当数据获取成功后调用 next
方法
export default {
data() {
return {
post: null,
error: null,
}
},
beforeRouteEnter(to, from, next) {
getPost(to.params.id, (err, post) => {
next(vm => vm.setData(err, post))
})
},
// 路由改变前,组件就已经渲染完了
// 逻辑稍稍不同
async beforeRouteUpdate(to, from) {
this.post = null
try {
this.post = await getPost(to.params.id)
} catch (error) {
this.error = error.toString()
}
},
}
在为后面的视图获取数据时,用户会停留在当前的界面,因此建议在数据获取期间,显示一些进度条或者别的指示。如果数据获取失败,同样有必要展示一些全局的错误提醒。