Vue.js - 路由 vue-router 的使用详解9(导航前、后自动获取数据)
作者:hangge | 2018-08-30 08:10
我们常常需要在通过路由进行跳转后,根据传递过来的参数去请求服务器数据。而这个数据请求操作可以放在导航完成前,也可以放在导航完成后。下面对这两种情况分别进行演示。

(2)而详情页(detail.vue)中,我们在 beforeRouteEnter() 这个钩子函数中获取数据,等数据获取成功后再执行导航。
(2)如果用到了 keep-alive,那么我们还需要使用 watch 监测路由变化,如果有变化再次去获取数据。否则只有第一次打开页面时会去请求。
一、导航完成之前获取数据
1,效果图
- 通过点击首页面的链接跳转到详情页,跳转时还会携带有具体的 id 值。
- 详情页需要先根据 id 获取到对应数据后,再进行跳转。(即页面渲染发生在页面请求之后)

2,样例代码
(1)首页代码(index.vue)很简单,这里我使用 params 方式传递参数。
<template>
<div>
<button @click="gotoDetail(101)">文章1</button>
<button @click="gotoDetail(102)">文章2</button>
<button @click="gotoDetail(103)">文章3</button>
</div>
</template>
<script>
export default {
name: 'index',
methods: {
gotoDetail(id) {
this.$router.push({
name:'detail',
params:{id: id}
});
}
}
}
</script>
(2)而详情页(detail.vue)中,我们在 beforeRouteEnter() 这个钩子函数中获取数据,等数据获取成功后再执行导航。
<template>
<div>
<h3>ID:{{ $route.params.id }}</h3>
<h3>结果:{{ result }}</h3>
</div>
</template>
<script>
export default {
name: 'detail',
data () {
return {
result: ""
}
},
//路由进入前调用
beforeRouteEnter (to, from, next) {
//传递过来的参数
var id = to.params.id;
//使用setTimeout模拟数据获取(等待2秒返回)
setTimeout(function(){
next(vm => {
vm.result = "这个是id=" + id + "的数据";
})
}, 2000);
}
}
</script>
二、导航完成之后获取数据
这个逻辑同上面的刚好相反:
- 我们先完成导航,然后再去请求数据。
- 同时在数据获取期间会显示一个 loading 指示器。数据返回后 loading 消失,并在页面上显示结果。

首页代码和之前一样,没有变化。主要是详情页这边的实现方式由几种,分别如下。
1,在 created() 方法中请求数据
(1)我们可以直接在组件的创建完毕方法(created)中去请求数据。注意:这个只适用于没有使用 keep-alive 进行缓存的情况。
<template>
<div>
<div class="loading" v-if="loading">
加载中....
</div>
<div>
<h3>ID:{{ $route.params.id }}</h3>
<h3>结果:{{ result }}</h3>
</div>
</div>
</template>
<script>
export default {
name: 'detail',
data () {
return {
loading: false,
result: ""
}
},
//组件创建完后调用
created () {
this.loading = true;
//传递过来的参数
var id = this.$route.params.id;
//使用setTimeout模拟数据获取(等待2秒返回)
var that = this;
setTimeout(function(){
that.loading = false;
that.result = "这个是id=" + id + "数据";
}, 2000);
}
}
</script>
<style>
.loading {
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100px;
height: 40px;
line-height: 40px;
background-color: #222222;
color: white;
text-align: center;
}
</style>
(2)如果用到了 keep-alive,那么我们还需要使用 watch 监测路由变化,如果有变化再次去获取数据。否则只有第一次打开页面时会去请求。
<template>
<div>
<div class="loading" v-if="loading">
加载中....
</div>
<div>
<h3>ID:{{ $route.params.id }}</h3>
<h3>结果:{{ result }}</h3>
</div>
</div>
</template>
<script>
export default {
name: 'detail',
data () {
return {
loading: false,
result: ""
}
},
methods:{
fetchData () {
this.loading = true;
//传递过来的参数
var id = this.$route.params.id;
//使用setTimeout模拟数据获取(等待2秒返回)
var that = this;
setTimeout(function(){
that.loading = false;
that.result = "这个是id=" + id + "数据";
}, 2000);
}
},
//组件创建完后调用
created () {
this.fetchData()
},
watch: {
//监听路由变化,获取数据
'$route' : 'fetchData'
}
}
</script>
2,在 beforeRouteEnter() 这个钩子函数中请求数据
和最开始的样例不同的是,我们这次在导航完成之后(next 回调)再去调用相关方法请求数据。(这种方式不受 keep-alive 缓存影响)
<template>
<div>
<div class="loading" v-if="loading">
加载中....
</div>
<div>
<h3>ID:{{ $route.params.id }}</h3>
<h3>结果:{{ result }}</h3>
</div>
</div>
</template>
<script>
export default {
name: 'detail',
data () {
return {
loading: false,
result: ""
}
},
methods:{
fetchData () {
this.loading = true;
//传递过来的参数
var id = this.$route.params.id;
//使用setTimeout模拟数据获取(等待2秒返回)
var that = this;
setTimeout(function(){
that.loading = false;
that.result = "这个是id=" + id + "数据";
}, 2000);
}
},
//路由进入前调用
beforeRouteEnter (to, from, next) {
next(vm => {
//导航完毕后再去请求数据
vm.fetchData();
});
}
}
</script>
全部评论(1)
作者提供一下案例下载吧
站长回复:这个就是完整的代码啊,你搭好项目,把代码复制进行就可以了。