Vue Router 数据获取

数据获取

有时候进入某个路由后,需要从服务器获取数据。

可从两种方式来实现:导航完成后获取、导航完成前获取。

导航完成后获取(先跳转,再渲染数据)

先完成导航,再在接下来的组件生命周期钩子(created)中获取数据。

数据获取期间,显示‘加载中’之类的提示。

注:最初始生命周期钩子created在全局后置钩子afterEach之后执行,也就是created()会在导航后执行

思路:

设置一个元素来显示‘loading’提示,v-if属性为data变量,初始值为false,一开始并不显示。

在created钩子中调用获取数据的方法。

在methods中定义获取数据的方法:向服务器发送请求前显示‘loading’提示,向服务器请求数据,请求方法的回调函数中关闭'loading'提示,并且将获取到的数据渲染到页面上。

在watch中监视'$route'路由对象,当路由发生变化,则会再次执行获取数据的方法。

实现:

<template>
  <div class="post">
    <div v-if="loading" class="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
      // replace getPost with your data fetching util / API wrapper
      getPost(this.$route.params.id, (err, post) => {
        this.loading = false
        if (err) {
          this.error = err.toString()
        } else {
          this.post = post
        }
      })
    }
  }
}

导航完成前获取(先渲染数据,再跳转)

导航完成前,在路由进入的守卫(beforeRouteEnter)中获取数据,在数据获取成功后执行导航。

注:在守卫中获取并渲染数据,肯定得选能使用this的守卫,全局的肯定不能用,只能用组件内守卫,一般使用beforeRouteEnter就可以了。

思路:

在beforeRouteEnter守卫中,向服务器发送请求,请求方法的回调函数中调用next(),next()参数设置回调函数,渲染数据。

因为只改变动态段的话,依然进入同一个组件,复用的组件并不会进入beforeRouteEnter守卫,而是会进入beforeRouteUpdate,所以还要另外添加一个beforeRouteUpdate,同样向服务器获取数据。

实现:

export default {
  data () {
    return {
      post: null,
      error: null
    }
  },
  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
      }
    }
  }
}

在为后面的视图获取数据时,由于是先渲染后导航(跳转),用户会停留在当前的界面,因此建议在数据获取期间,显示一些进度条或者别的提示。如果数据获取失败,同样有必要展示一些全局的错误提醒。

posted @ 2021-10-18 01:36  慕斯星球  阅读(669)  评论(0)    收藏  举报