数据获取

有时,进入某个路由之后,需要从服务器获取数据,可以通过两种方式实现:

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>