有时,进入某个路由之后,需要从服务器获取数据,可以通过两种方式实现:
1,导航完成之后获取
① 先完成导航,然后在接下来的组件的生命周期钩子函数中获取数据,在数据获取期间显示“加载中” 之类的指示
② 当使用这种方式时,我们会马上导航和渲染组件,然后在组件的 created 钩子中获取数据,这样我们有机会在数据获取期间展示一个 loading,还可以在不用视图间展示不同的 loading
③ 如,当导航到 /user/userA 组件时,UserA 组件需要获取用户数据
UserA.vue
<template> <div> <div class="box">UserA</div> <h3 v-if="loading">Loading.....</h3> <h3 v-if="error">{{error}}</h3> <h3 v-if="data">{{data[0].body}}</h3> </div> </template> <script> import axios from "axios"; export default { data: function() { return { loading: null, error: null, data: null }; }, created() { this.getData(); //组件创建完成后获取数据,此时data已经被 observed了 }, watch: { $route: "getData" // 路由变化,再次获取数据 }, methods: { async getData() { this.loading = true; const res = await axios.get("http://jsonplaceholder.typicode.com/posts"); this.loading = false; if (res.status === 200) this.data = res.data; else this.error = res.statusText; } } }; </script> <style scoped> .box { 100px; height: 100px; background-color: lightgreen; } </style>
2,导航完成之前获取
① 导航完成前,在路由进入的守卫中获取数据,在数据获取成功后执行导航
② 通过这种方式,在导航转入新的路由之前获取数据,在接下来的组件的 beforeRouteEnter 守卫中获取数据,当数据获取成功后调用 next 方法
③ 如,当导航到 /user/userB 组件时,UserB 组件需要获取数据
<template> <div> <div class="box">UserB</div> <div v-if="loading">Loading....</div> <div v-if="error">{{ error }}</div> <div v-if="data">{{ data[0].username }}</div> </div> </template> <script> import axios from "axios"; export default { data: function() { return { loading: false, error: null, data: null }; }, beforeRouteEnter(to, from, next) { next(vm => { vm.getData(vm); }); }, // 不同于beforeRouteEnter,beforeRouteUpdate是路由改变之前,组件已经渲染完毕 beforeRouteUpdate(to, from) { this.getData(this); }, methods: { async getData(CurComponent) { CurComponent.loading = true; const res = await axios.get("http://jsonplaceholder.typicode.com/users"); console.log(res) CurComponent.loading = false; if (res.status === 200) CurComponent.data = res.data; else CurComponent.error = res.statusText; } } }; </script> <style scoped> .box { 100px; height: 100px; background-color: pink; } </style>