<template>
<div class="post">
<!-- 正在获取数据时,展示 loading 状态 -->
<div class="loading" v-if="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 () {
// 组件创建完后获取数据,
// 此时 data 已经被 observed 了
this.fetchData()
},
watch: {
// 如果路由有变化,会再次执行该方法
'$route': 'fetchData'
},
methods: {
fetchData () {
this.error = this.post = null
this.loading = true
// 这里的 getPost 只是个示例,你可以用自己封装好的 API 来替代
getPost(this.$route.params.id, (err, post) => {
this.loading = false
if (err) {
this.error = err.toString()
} else {
this.post = post
}
})
}
}
}
通常在导航后获取数据时,路由先进行跳转,组件也被渲染出来。如果获取数据再进行处理,速度如果比较慢的话,可以考虑加上 loading 状态,否则数据展示区域在处理完之前将是一片空白。
export default {
data () {
return {
post: null,
error: null
}
},
// beforeRouteEnter 调用时,组件示例还没有被创建,因此不能通过 this 访问组件实例,
// 只能通过给 next 传递一个回调函数来访问,该回调函数会被传入组件实例,
// 这个钩子函数是唯一一个 next 支持传入回调函数的
beforeRouteEnter (to, from, next) {
getPost(to.params.id, (err, post) => {
next(vm => vm.setData(err, post))
})
},
// 路由改变前,组件就已经渲染完了,逻辑稍稍不同
beforeRouteUpdate (to, from, next) {
this.post = null
getPost(to.params.id, (err, post) => {
this.setData(err, post)
next()
})
},
methods: {
setData (err, post) {
if (err) {
this.error = err.toString()
} else {
this.post = post
}
}
}
}