前端 实现数据的分批加载

6 篇文章 1 订阅
5 篇文章 0 订阅

UNI-APP上拉分段加载数据

当服务端数据没有进行分页处理时,ajax请求一次接口返回所有的数据;当请求数据过多的时候页面渲染会非常慢,并且很容易造成页面卡死现象;因此,前端可以通过js进行分页,达到分批加载数据的目的。

思路:
1、获取数据的分段处理
  (1)无数据
不显示加载状态栏
显示无数据信息提示
  (2)有数据
在这里插入图片描述

  • 动态设置API参数取值

加载数据时动态改变API参数值,这里设置time来控制,追加数据时time++,确保查询的追加数据条数比上次获取的数据多十条。

  • 分段截取数据

以index为索引连续抽取十条数据放进定义的数组listArr(相当于中转器)中,根据reload值判断数据是第一次加载还是再次加载(这里统一说成追加数据)

  • 组合分段数据显示

将截取的追加数据和第一次加载的数据连接起来赋给最终list,通过template中的v-for循环显示在客户端

2、加载状态切换处理

(1)渲染初加载完页面设置为‘上拉加载更多’
  (2)上拉到底设置为‘加载中’,这里通过判断是否为追加数据进行设置
  (3)数据加载完毕设置为‘没有更多’
    根据传递的条数值size和实际得到数据长度之差来判断数据是否加载完毕,如果不为0则表示加载完毕,此时设置loadingFlag控制上拉到底时不再触发数据加载

v-for 中可以使用slice或者splice获取数组中的特定部分进行输出:

<view class="lj_spdan" v-for="(item,index) in commodity.slice(0, load_shulian)" :key="index"></view>

代码:

<template>
      <view class="">
            <view class="tishiXinxi" v-if="anzhuangXinxi">
                  没有现场安装申请信息
            </view>
            <view class="apply_list_box" v-for='(item,index) in list' :key="index">
                  <view class="apply_list">
                        <image class="photo_head" src="/static/qingjia_bg.png" mode=""></image>
                        <view class="apply_list_text">
                              <view class="text_1">{{item.processDefinitionName}}</view>
                              <button type="primary" @tap="riZhi" :data-id='item.id'>流程日志</button>
                              <view class="text_2">{{item.startTime}}</view>
                        </view>
                  </view>
                  <view class="xiaoxi_line"></view> 
            </view>
            <uni-load-more :status="status" :content-text="contentText" /><!-- 加载列表 -->
      </view>
</template>

<script>
import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue';
var app = getApp();
export default {
      data() {
            return {
                  proInstId: '',
                  templateId:'',
                  last_id: '',
                  list:[],
                  anzhuangXinxi:false,
                  reload:true,//判断是否为第一轮加载,以便赋予index值
                  time:2,//该值是为了动态更新向服务器传递的参数值
                  index:0,//为获取的数据进行分段处理,十条数据一加载
                  loadingFlag:true,//判断是否继续上拉加载数据
                  status: 'more',//加载状态
                  contentText: {
                        contentdown: '上拉加载更多',
                        contentrefresh: '加载中',
                        contentnomore: '没有更多'
                  }
            };
      },
      onLoad(option) {
            this.templateId = option.templateId;
      },
      onShow(){
            this.getList();
      },
      onReachBottom() {
            if(this.loadingFlag==true){
                  this.status = 'more';
                  this.getList();
            }
      },
      methods: {
            getList: function(){
                  var that = this;
                  var Authorization = app.globalData.Authorization;
                  const data = {
                        '流程模板key':'process_setup',
                        page:1,
                        size:10
                  };
                  if (that.last_id) {
                        //说明已有数据,目前处于上拉加载
                        that.status = 'loading';
                        data.size = 10*that.time;
                        that.time++;
                  }
                  console.log("data:"+JSON.stringify(data));
                  this.$servers
                        .globalRequest('actApi/my', 'POST', data, Authorization)//此处封装了AJAX,只要能获取到接口数据,怎样都成
                        .then(res => {
                              let listData = res.data.data;
                              console.log("listData:"+listData.length);
                              var num = data.size-listData.length;
                              var listArr= [];
                              if(that.reload==true && listData.length==0){
                                    that.anzhuangXinxi = true;
                                    that.contentText = '';
                                    return false;
                              }else{
                                    if(that.reload==false){
                                          that.index +=10;
                                    }
                                    if(num!=0){
                                          that.status = 'noMore';
                                          that.loadingFlag = false;
                                    }
                                    for(var j=that.index;j<(that.index+10>=listData.length?listData.length:that.index+10);j++){
                                          listArr.push(listData[j]);
                                    }
                                    that.last_id = listArr[listArr.length-1].id;
                                    that.list = that.reload ? listArr : that.list.concat(listArr);
                                    that.list.sort(function(a, b) {
                                          return a.startTime < b.startTime ? 1 : -1;
                                    });
                                          this.reload = false;
                                    }
                              })
                        .catch(parmas => {});
                  }
            }
      };
</script>

一、技术点
使用vue+es6+axios+mock.js。这里mock了32条随机数据,不熟悉的小伙伴请翻阅mock.js官方文档进行学习。

1、vue.js
2、mock.js
3、axios.js

原理
利用slice截取前5条数据(如arr.slice(0,5)),当点击加载更多时累加5条数据(arr.slice(5,10)),然后把数组里的obj数据push到一个变量里,然后用vue来进行模板渲染。

这里,熟悉一下slice()的用法:
slice() 可从已有的数组中返回选定的元素

语法:arrayObject.slice(start,end)
start 必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。

end 可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。

注意了~ slice()和splice()名字上用法上容易混淆,请小伙伴们自行百度,这里一笔带过。

四、代码

//mock.js 随机模拟32条数据

"data|32": [{
  "id|+1": 1,
  "title": "@title"
}]

//vue中data数据

data: {
  list: [],    //存放数据容器
  page: 0,    //第一条数据
  number: 5    //第五条数据
}

//vue生命周期默认加载请求前5条数据

created(){
  axios.get('xxx')
  .then((res) => {
    console.log(res);
    if(res.status == "200"){
      console.log(res.data.data);
      this.list = res.data.data.slice(this.page, this.number);
    }
  })
  .catch((error) => {
    console.log(error);
  })
}

//点击加载更多

methods: {
  onLoad(){
    //累加5条数据
    this.page = this.page + 5; 
    this.number = this.number + 5; 
    // 截取后返回的是一个数组对象 
    axios.get('xxx')
    .then((res) => {
      console.log(res);
      if(res.status == "200"){
        let data = res.data.data.slice(this.page, this.number);
        console.log(data);
        data.forEach((item, index) => {
          //因此只需要遍历里面的对象 因为数组push不进数组 push对象到数组里即可
          console.log(item);
          this.list.push(item);
        })
        //咳咳 用push方法有点麻烦 竟然返回数组直接用concat()拼接就可以了 emmm... 而且在小程序里上拉加载push数据不会叠加数据~
      }
    })
    .catch(function (error) {
      console.log(error);
    })
  }
}

//html

<div class="list">
   <p v-for="(item,index) in list" :key="index" :id="item.id">{{item.title}}</p>
</div>
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

织_网

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

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

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

打赏作者

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

抵扣说明:

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

余额充值