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