精通Vue.js系列 │ 路由导航中抓取数据

简介: 当用户在浏览器端进行路由导航时,有些目标路由的组件需要从服务器端抓取数据,再把这些数据显示到网页上。抓取数据有以下两种方式。(1)导航后抓取:在导航完成后,在目标路由的组件的生命周期函数中抓取数据。在抓取的过程中,可以在网页上显示“正在加载中...”的提示信息。(2)导航前抓取:先在导航守卫函数beforeRouteEnter()和beforeRouteUpdate()中抓取数据,接下来再进行导航。以上两种方式都能完成抓取任务,到底选用哪一种,取决于开发人员的喜好及开发团队的要求。

640.jpg


当用户在浏览器端进行路由导航时,有些目标路由的组件需要从服务器端抓取数据,再把这些数据显示到网页上。抓取数据有以下两种方式。

(1)导航后抓取:在导航完成后,在目标路由的组件的生命周期函数中抓取数据。在抓取的过程中,可以在网页上显示“正在加载中...”的提示信息。

(2)导航前抓取:先在导航守卫函数beforeRouteEnter()和beforeRouteUpdate()中抓取数据,接下来再进行导航。

以上两种方式都能完成抓取任务,到底选用哪一种,取决于开发人员的喜好及开发团队的要求。

1、导航后抓取

例程1定义了ItemPostFetch组件,在它的created()钩子函数中,调用$watch()函数监听$route.params变量,如果该变量发生更新,就会执行fetchData()方法。该$watch()函数的第三个参数{ immediate: true }确保在ItemPostFetch组件的初始化阶段也会执行一次fetchData()方法。

fetchData()方法负责抓取数据,在实际应用中,会通过Ajax请求到服务器端抓取数据,本方法做了简化,通过setTimeOut()函数模拟耗时的抓取数据的行为。

■ 例程1 ItemPostFetch.vue

<template>
  <div>
    <div v-if="isLoading" >商品数据加载中...</div>
    <div v-if="isError" >商品数据加载失败</div>
    <div v-if="isReady">
      <p>商品ID: {{item.id}}</p>
      <p>商品名字: {{item.title }} </p>
      <p>商品描述: {{item.desc}}</p>
    </div>
  </div>
</template>

<script>
  import Items from '@/assets/items'  //引入Item数据
  export default {
    data() {
      return {
        item: {},
        isLoading: false,
        isReady: null,
        isError: null 
      }
    },
    created() {
      //监听$route.params,如果发生更新,就调用fetchData()方法
      this.$watch(
        () => this.$route.params,
        () => {
          this.fetchData()
        },
        //确保在初始化组件时也调用一次fetchData()方法
        { immediate: true }
      )
    },
    methods: {
      fetchData() {
        this.isReady = null
        this.isError=null
        this.isLoading = true
        //模拟耗时的抓取数据行为,在实际应用中会到服务器端抓取数据
        setTimeout(
          ()=>{
             this.item=Items.find(
               (item)=>item.id==this.$route.params.id
             )
            if(this.item){
              //如果存在与id匹配的商品数据,就显示商品数据
              this.isLoading=false
              this.isReady=true
            }else{
              //如果不存在与id匹配的商品数据,就显示错误信息
              this.isLoading=false
              this.isError=true
            }
          },2000) //延迟2秒后执行数据抓取
      }
    }
  }
</script>

在index.js中,为ItemPostFetch组件设置如下路由:

{
      path: '/postfetch/:id',
      component: ItemPostFetch
    }

通过浏览器访问http://localhost:8080/#/postfetch/1,会看到网页上首先显示“商品数据加载中...”,接下来再显示id为1的商品信息。

通过浏览器访问http://localhost:8080/#/postfetch/5,会看到网页上首先显示“商品数据加载中...”,接下来再显示“商品数据加载失败”。

2、导航前抓取

在例程2定义了ItemPreFetch组件。在beforeRouteEnter()和beforeRouteUpdate()导航守卫函数中都会通过fetchData()函数抓取数据。fetchData()是一个独立的函数,不属于ItemPreFetch组件。fetchData()函数有一个作为回调函数的callback参数,当抓取数据完毕后,callback回调函数会把item变量和isError变量赋值给ItemPreFetch组件的item变量和isError变量。

由于在beforeRouteEnter()函数中不能通过this关键字访问ItemPreFetch组件,因此通过next()函数来为ItemPreFetch组件的item变量和isError变量赋值。

■ 例程2 ItemPreFetch.vue

<template>
  <div>
    <div v-if="isError" >商品数据加载失败</div>
    <div v-if="! isError">
      <p>商品ID: {{item.id}}</p>
      <p>商品名字: {{item.title }} </p>
      <p>商品描述: {{item.desc}}</p>
    </div>
  </div>
</template>

<script>
  import Items from '@/assets/items'   //引入Item数据

  function  fetchData(id,callback) {
    let isError=null
    let item=null 
    //模拟耗时的抓取数据行为,在实际应用中会到服务器端抓取数据
    setTimeout(
      ()=>{
        item=Items.find(
          (item)=>item.id==id
        )
        if(item){
          isError=false
        }else{
          isError=true
        }
        callback(item,isError)
    },2000) //延迟2秒后执行数据抓取
  }

  export default {
    data() {
      return {
        item: {},
        isError: null 
      }
    },
    beforeRouteEnter(to, from, next) {
      fetchData(to.params.id,
        (item, isError) => {
           next(vm => {
             vm.item=item
             vm.isError=isError
           })
        }
      )
    },
    beforeRouteUpdate(to) {
      fetchData(to.params.id,
        (item, isError) => {
           this.item=item
           this.isError=isError
        }
      )
    }
  }
</script>

beforeRouteEnter()函数如果不使用next参数,还可以改写为:

beforeRouteEnter(to) {
    fetchData(to.params.id,
        (item, isError) => {
           return vm => {
             vm.item=item
             vm.isError=isError
           }
        }
    )
  }

在index.js中,为ItemPreFetch组件设置如下路由:

{
      path: '/prefetch/:id',
      component: ItemPreFetch
    }

通过浏览器访问http://localhost:8080/#/prefetch/1,会看到网页首先停留在原来的页面,接下来再显示id为1的商品信息。

通过浏览器访问http://localhost:8080/#/prefetch/5,会看到网页首先停留在原来的页面,接下来再显示“商品数据加载失败”。

目录
相关文章
|
15小时前
|
JavaScript 前端开发 程序员
探索Vue.js宝库:解锁基础知识与实用技能之门(1. 数据绑定与响应式 2. 条件与循环 3. 组件化开发;1. 路由管理与导航 2. 状态管理与Vuex 3. Vue.js的生命周期)
探索Vue.js宝库:解锁基础知识与实用技能之门(1. 数据绑定与响应式 2. 条件与循环 3. 组件化开发;1. 路由管理与导航 2. 状态管理与Vuex 3. Vue.js的生命周期)
8 1
|
15小时前
|
JavaScript 前端开发
Vue.js中使用JavaScript实现路由跳转详解
Vue.js中使用JavaScript实现路由跳转详解
2 0
|
1天前
|
JavaScript 前端开发 网络架构
Vue如何实现页面跳转路由,实现单页面跳转
Vue如何实现页面跳转路由,实现单页面跳转
|
1天前
|
JavaScript 网络架构
vue3 Elementplus 动态路由菜单不跳转问题
vue3 Elementplus 动态路由菜单不跳转问题
12 1
|
3天前
|
JavaScript API 网络架构
Vue3路由机制router(2)
Vue3路由机制router(2)
9 0
|
3天前
|
安全 定位技术 数据安全/隐私保护
Vue3路由机制router(1)
Vue3路由机制router(1)
9 0
|
3天前
|
JavaScript 网络架构
vue路由跳转之【编程式导航与传参】
vue路由跳转之【编程式导航与传参】
|
3天前
|
JavaScript
vue路由从入门到进阶 --- 路由重定向与404等问题
vue路由从入门到进阶 --- 路由重定向与404等问题
|
4天前
|
JavaScript 前端开发 网络架构
4.vue路由
4.vue路由
10 1