>>分享孙卫琴的Java技术专稿和著作 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 8364 个阅读者 刷新本主题
 * 贴子主题:  【Vue.js技术专题】路由导航中抓取数据 回复文章 点赞(0)  收藏  
作者:sunweiqin    发表时间:2022-08-29 17:39:49     消息  查看  搜索  好友  邮件  复制  引用

本文参考孙卫琴,杜聚宾所创作的 <<精通Vue.js: Web前端开发技术详解>>一书

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

1.导航后抓取

例程1的ItemPostFetch.vue定义了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.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”,会看到网页首先停留在原来的页面,接下来再显示“商品数据加载失败”。



程序猿的技术大观园:www.javathinker.net
  Java面向对象编程-->Swing组件(下)
  JavaWeb开发-->Web运作原理(Ⅲ)
  JSP与Hibernate开发-->Java应用分层架构及软件模型
  Java网络编程-->创建非阻塞的HTTP服务器
  精通Spring-->通过Axios访问服务器
  Vue3开发-->Vue指令
  【Vue.js技术专题】路由管理器的基本用法
  【Vue.js技术专题】在Vue项目中使用Axios
  【Spring专题】控制器对象的生命周期
  【Spring专题】Spring框架的数据验证机制
  【Spring专题】通过JPA API实现Repository接口
  【Spring专题】@Query和@Modifying注解的增删改操作
  【持久化专题】JPA API的级联操作
  【持久化专题】映射一对多双向关联关系
  【持久化专题】@Enumerated注解映射枚举类型
  【持久化专题】对象-关系的映射概念
  【持久化专题】映射Bag包(值类型的集合)
  【Java网络编程专题】用Apache HttpClients下载网上的图片等...
  【JavaWeb专题】在JavaWeb应用中对客户请求的异步处理
  【JavaWeb专题】Spring MVC创建Web应用范例,轻松入门
  《大话Java程序设计从入门到精通》写作花絮
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。