精通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,会看到网页首先停留在原来的页面,接下来再显示“商品数据加载失败”。

目录
相关文章
|
5天前
|
API
vue3知识点:响应式数据的判断
vue3知识点:响应式数据的判断
14 3
|
5天前
|
资源调度 JavaScript 前端开发
路由管理:Vue Router的使用和配置技巧
【10月更文挑战第21天】路由管理:Vue Router的使用和配置技巧
15 3
|
6天前
|
存储 缓存 JavaScript
vue表单案例练习:vue表单创建一行数据及删除数据的实现与理解
vue表单案例练习:vue表单创建一行数据及删除数据的实现与理解
22 2
|
8天前
|
缓存 JavaScript 搜索推荐
Vue Router 导航钩子的使用场景
【10月更文挑战第13天】
8 1
|
8天前
|
JavaScript 搜索推荐 数据处理
Vue Router 导航钩子
【10月更文挑战第17天】需要注意的是,过度使用导航钩子可能会导致代码复杂度增加,因此需要合理规划和使用。此外,不同的钩子在不同的场景下具有不同的作用,需要深入理解其特点和用法,才能更好地发挥它们的价值。可以在实际项目中结合具体需求,充分利用这些导航钩子来打造更加智能、灵活的路由导航机制。
9 1
|
13天前
|
JavaScript API
vue 批量自动引入并注册组件或路由等等
【10月更文挑战第12天】 vue 批量自动引入并注册组件或路由等等
|
13天前
|
JavaScript 前端开发 API
vue3中常用插件的使用方法:按需引入自定义组件,自动导入依赖包,自动生成路由,自动生成模拟数据
vue3中常用插件的使用方法:按需引入自定义组件,自动导入依赖包,自动生成路由,自动生成模拟数据
283 0
|
13天前
|
JavaScript 前端开发 UED
vue中vue-router路由懒加载(按需加载)的作用以及常见的实现方法
vue中vue-router路由懒加载(按需加载)的作用以及常见的实现方法
88 1
|
20天前
|
JavaScript UED 开发者
Vue中的导航守卫有哪三种?分别有什么作用
Vue中的导航守卫有哪三种?分别有什么作用
|
20天前
|
JavaScript 前端开发 UED