首先,这是个真实的案例,我大兄弟在深圳开汽修店铺,但需要系统来管理日常经营活动,这正不是我擅长的吗?

说干就干,直接后端+web端+移动端来一套,于是紧急赶工,起早摸黑,产出约3万行总量代码,此系统与工作无关,

纯属个人业余开发,所以我敢拿来任意剖析,如果有时间我就出个连载,做一些典型的技术解析。这次说下移动端开发,

考虑到适配和多端问题,还有效率原因,我选择了混合模式,即原生做壳,H5+CSS做内容展现,JS代码实现逻辑,

然后用第三方工具打包生成移动App,我们来看下懒加载模式。

准备:

Idea2019.03/Gradle6.0.1/JDK11.0.4/Lombok0.28/SpringBoot2.2.4RELEASE/mybatisPlus3.3.0/Soul2.1.2/Dubbo2.7.5

/Mysql8.0.11/Vue2.5/OSS/Hbuilder2.6.1

难度: 新手--战士--老兵--大师

目标:

1.前端展现数据懒加载实现

步骤:

为了遇见各种问题,同时保持时效性,我尽量使用最新的软件版本。代码地址:https://github.com/xiexiaobiao/vehicle-shop-mobile.git

1 本套系统大体情况

后端代码量约1.5万,双前端约1.5万,技术还是很具代表性的,不然就不好意思拿出来说事了,详细可看Git库说明,下图是后端代码量分析:

Web管理界面:

手机端:使用Hbuilder编码,Uniapp框架,再随手捡了几个UI拿来大改了几下,基本形状如下:

2 数据懒加载

比如上图中商品页和订单列表页,数据流量还是很大的,因为里面参杂了图片,如果一上来就一股脑全加载,再搞个前端缓存假分页加载,那你得考虑下用户的

感受!因此需要懒加载,或者叫渐进式加载,必须得结合后端物理分页实现。

思路:后端物理分页,前端首次进页面,先请求一次后端并加载到页面,后续操作中页面滑到底后自动触发后续加载并请求后端,将返回数据累加到前端缓存数组,

再加载到页面,直到数据全部完毕。

首先定义后端(有点不规范,把数据处理写在controller层,没来得及优化):

com.biao.shop.stock.controller.ShopItemController:

@GetMapping("/item/list")
public ObjectResponse<Page<ShopItemEntityDto>> listItem(@RequestParam("pageNum") int current, @RequestParam("pageSize")int size,
@RequestParam(value = "itemName",required = false) String itemName,
@RequestParam(value = "itemUuid",required = false)String itemUuid,
@RequestParam(value = "category",required = false) String category,
@RequestParam(value = "brandName",required = false)String brandName,
@RequestParam(value = "shipment",required = false) Integer shipment){
int shipmentTemp = Objects.isNull(shipment)? 2: shipment;
// 这里的shipment最好设计为int,可以接收 0 1 2 ,boolean型,只能是0 1,前端传来都会自带默认0,导致无法查询无此条件限制的
Page<ShopItemEntityDto> pageInfo = shopItemService.listItem(current,size,itemName,itemUuid,category,brandName,shipmentTemp);
ObjectResponse<Page<ShopItemEntityDto>> response = new ObjectResponse<>();
response.setCode(RespStatusEnum.SUCCESS.getCode());
response.setMessage(RespStatusEnum.SUCCESS.getMessage());
response.setData(pageInfo);
return response;
}

以上代码是controller层,具体后端服务实现我就省略了,请看Git源码,返回给web端是个简单的统一返回封装,

ObjectResponse{"code":200,"message":"SUCCESS","data":{Object}},其数据就是Page类型,具体是MybatisPlus中的

com.baomidou.mybatisplus.core.metadata.Ipage, 包含了数据总量,当前页数和每页的量,来个例子就是下面这样的:

{"code":200,"message":"SUCCESS","data":{"records":[{"idItem":2,"itemUuid":"SP000011","category":"修理","classification":null,"itemName":"雨刮器","sellPrice":60.99,"purchasePrice":45.99,"brandName":"奔驰系列","description":"奔驰系列","shipment":null,"alertQuantity":5,"specification":"35*35cm","unit":"支","picAddr":"https://biao-aliyun-oss-pic-bucket.oss-cn-shenzhen.aliyuncs.com/images/logo-samll.png","stock":null,"sales":null,"discountPrice":null}],"total":23,"size":500,"current":1,"orders":[],"searchCount":true,"pages":1}

那前端就是先定义一个初始请求的量,初始页值必须为 1,然后是每次懒加载的页面数据量,这里有个很隐蔽的地方,

必须保证首次懒加载的页面数据量填满屏幕,否则无法触发屏幕触底上滑加载:

pages\product\list.vue文件

data() {
return {
// 分页实现页面懒加载
pageInfo:{
"total": 0,
"size": 6, // 每次懒加载的页面数据量
"current":1// 首次请求的初始页值,之后每请求一次就累加 1
},
...
}

每次请求数据的方法封装一下:

requesForData:function(){
Request().request({
url:'stock/vehicle/stock/item/list',
method: 'get',
header:{},
params: {
'pageNum': this.pageInfo.current,
'pageSize': this.pageInfo.size,
},
}
).then(
res => {
let pdtArr = res.data.records;
this.goodsList = this.goodsList.concat(pdtArr);
// 懒加载机制 --> 加载一次后累加页数
this.pageInfo.total = res.data.total;
this.pageInfo.current += 1;
}
).catch(err => {
console.error('is catch', err)
this.err = err;
});

以上代码中,要实现懒加载机制,需每次加载一次后累加当前页数,另外使用Array.concat函数,追加到已有的数组后面,这样懒加载基本就成型了!

3 如何触发每次的懒加载?

方法一:uniapp页面有个自带的钩子:

//加载更多
onReachBottom(){
console.log("onReachBottom")
this.loadData();
},

方法二:页面模板中的scroll-view元素,加上@scrolltolower事件函数:

<scroll-view
class="list-scroll-content"
scroll-y
@scrolltolower="loadData"
:refresher-enabled = "false"
>

同时配合:

<uni-load-more :status="tabItem.loadingType"></uni-load-more>

当然,必须有个指示器,告知数据是否全部完毕了, 在loadData方法中最后加一个判断:

//判断是否还有数据, 有改为 more, 没有改为noMore
if(this.pageInfo.total > (this.pageInfo.current-1) * this.pageInfo.size){
navItem.loadingType = 'more';
}elseif(this.pageInfo.total <= (this.pageInfo.current-1) * this.pageInfo.size){
navItem.loadingType = 'noMore';
}

收工结束!

后记:

  1. 懒加载必须配合后端的物理分页机制实现,
  2. 避免数据前端过滤后导致页面数据没法到达屏幕底部,结果全部数据完毕还没完,但已有的数据却不满一屏,这就不能自动触发事件了!所以,必须禁止懒加载模式下前端数据过滤,即带条件后端查数据,
  3. 数据加载,要注意与页面渲染的前后顺序,不然页面元素都渲染完了,你数据还没来就尴尬了,上面的后端数据请求可以看到,现在axios都是异步的,返回Promise对象,目前最新的解决办法就是可以使用 async / await 来保证异步代码的执行顺序,但是一定注意 await 后必须是返回Promise对象,否则不保证代码顺序!如果出现页面加载完了,数据还没出来,可以多写几个console.log(),看是否页面渲染在前,数据返回在后。
  4. 不要看上面我只说了很少,这只是核心和思路,具体实现还是要费点心思的。

全文完!


我的其他文章:

只写原创,敬请关注

H5开发移动应用APP(店铺系列一)的更多相关文章

  1. Anyoffice -HTML5大赛 悦心(基于H5开发安卓音乐app)-项目总结

    项目在线演示地址:http://rose111.applinzi.com/ github 地址:欢迎star https://github.com/midoxinxin/YueX-Music 悦心,一 ...

  2. MUI框架开发HTML5手机APP(一)--搭建第一个手机APP

      前  言 JRedu 随着HTML5的不断发展,移动开发成为主流趋势!越来越多的公司开始选择使用HTML5开发手机APP,而随着手机硬件设备配置的不断提升,各种开发框架的不断优化,也使着H5开发的 ...

  3. MUI框架开发HTML5手机APP(一)--搭建第一个手机APP(转)

    出处:http://www.cnblogs.com/jerehedu/p/7832808.html  前  言 JRedu 随着HTML5的不断发展,移动开发成为主流趋势!越来越多的公司开始选择使用H ...

  4. MUI框架开发HTML5手机APP

    出处:http://www.cnblogs.com/jerehedu/p/7832808.html  前  言 JRedu 随着HTML5的不断发展,移动开发成为主流趋势!越来越多的公司开始选择使用H ...

  5. 原生开发、H5开发、混合移动开发的优缺点

    一.原生开发(Native App开发) 原生开发,是在Android.IOS等移动平台上利用官方提供的开发语言.开发类库.开发工具进行App开发.比如Android是利用Java.Eclipse.A ...

  6. 关于APP,原生和H5开发技术的争论

    App的开发技术,目前流行的两种方式,原生和Html5.原生分了安卓平台和ios平台(还有小众的黑莓.死去的塞班就不说了),H5就是Html5. 目前争论不休的问题,在早先前争论CS,BS架构的软件系 ...

  7. H5外包团队 H5开发微信APP的优势有哪些

    H5外包团队 H5开发微信APP的优势有哪些

  8. 用H5开发微信还是开发APP?

    用H5开发微信还是开发APP? 随着技术的飞速发展,HTML第五版技术标准的更新,在移动端,由于其相对较低的开发成本及强大的跨平台运行能力,越来越多的信息型产品也开始选择这样轻量级的H5页面进行快速迭 ...

  9. 关于APP,原生和H5开发技术的争论 APP开发技术选型判断依据

    关于APP,原生和H5开发技术的争论 App的开发技术,目前流行的两种方式,原生和Html5.原生分了安卓平台和ios平台(还有小众的黑莓.死去的塞班就不说了),H5就是Html5. 目前争论不休的问 ...

随机推荐

  1. 传输层TCP和UDP

    TCP协议        传输控制协议        TCP是面向连接.可靠的进程到进程通信的协议        TCP提供全双工工服务,即数据可在同一时间双向传输        三次握手:      ...

  2. 【flask】RestFul的基本鉴权

    编写API的基本鉴权 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Author : shenqiang from flask import Fla ...

  3. python后端向前台返回字节流文件

    python后端向前台返回字节流文件,浏览器访问地址自动下载文件: from django.http.response import StreamingHttpResponse # 要下载的文件路径 ...

  4. MySQL数据库优化、设计与高级应用

    MySQL数据库优化主要涉及两个方面,一方面是对SQL语句优化,另一方面是对数据库服务器和数据库配置的优化. 数据库优化 SQL语句优化 为了更好的看到SQL语句执行效率的差异,建议创建几个结构复杂的 ...

  5. 关于(int argc char **argv)

    演示使用opencv显示一幅图片: #include <iostream> #include <core/core.hpp> #include <highgui/high ...

  6. chop|divorce|harsh|mutual|compel|

    这个英音很special VERB 砍;剁;劈;切If you chop something, you cut it into pieces with strong downward movement ...

  7. Ionic3学习笔记(十四)使用 videogular2 实现视频播放以及遇到的一些问题

    本文为原创文章,转载请标明出处 目录 使用 videogular2 安装 增加图标.字体支持 导入 module 举个例子 遇到的问题 iOS 端自动进入全屏播放 Android 端 autoplay ...

  8. 吴裕雄--天生自然 R语言开发学习:时间序列

    #-----------------------------------------# # R in Action (2nd ed): Chapter 15 # # Time series # # r ...

  9. 通用 mapper的简单使用

    通用 MAPPER的简单使用 官方  https://mapperhelper.github.io/docs/2.use/ 依赖 <dependency> <groupId>t ...

  10. python __import__动态模块

    1.只限解释器内部自己使用. 条件:test.lianx_2.py中的代码: class a(object): def __init__(self,name): self.name=name def ...