孙卫琴的《精通Vue.js》读书笔记-路由导航中抓取数据

本文介绍Vue.js中两种路由数据加载方法:导航后抓取和导航前抓取。通过实例展示了如何在组件生命周期的不同阶段抓取数据,并在界面上显示加载状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文参考孙卫琴,杜聚宾所创作的 <<精通Vue.js: Web前端开发技术详解>>一书
在这里插入图片描述
当用户在浏览器端进行路由导航时,有些目标路由的组件需要从服务器端抓取数据,再把这些数据显示到网页上。抓取数据有两种方式:
(1)导航后抓取:在导航完成后,在目标路由的组件的生命周期函数中抓取数据。在抓取的过程中,可以在网页上显示“正在加载中…”的提示信息。
(2)导航前抓取:先在导航守卫函数beforeRouteEnter()和beforeRouteUpdate()中抓取数据,接下来再进行导航。
以上两种方式都能完成抓取任务,到底选用哪一种,取决于开发人员的喜好以及开发团队的要求。

1.导航后抓取

例程1的ItemPostFetch.vue定义了ItemPostFetch组件,在它的created()钩子函数中,调用 w a t c h ( ) 函数监听 watch()函数监听 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.vue中定义了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”,会看到网页首先停留在原来的页面,接下来再显示“商品数据加载失败”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java技术集锦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值