H5开发移动应用APP(店铺系列一)
首先,这是个真实的案例,我大兄弟在深圳开汽修店铺,但需要系统来管理日常经营活动,这正不是我擅长的吗?
说干就干,直接后端+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';
}
收工结束!
后记:
- 懒加载必须配合后端的物理分页机制实现,
- 避免数据前端过滤后导致页面数据没法到达屏幕底部,结果全部数据完毕还没完,但已有的数据却不满一屏,这就不能自动触发事件了!所以,必须禁止懒加载模式下前端数据过滤,即带条件后端查数据,
- 数据加载,要注意与页面渲染的前后顺序,不然页面元素都渲染完了,你数据还没来就尴尬了,上面的后端数据请求可以看到,现在axios都是异步的,返回Promise对象,目前最新的解决办法就是可以使用 async / await 来保证异步代码的执行顺序,但是一定注意 await 后必须是返回Promise对象,否则不保证代码顺序!如果出现页面加载完了,数据还没出来,可以多写几个console.log(),看是否页面渲染在前,数据返回在后。
- 不要看上面我只说了很少,这只是核心和思路,具体实现还是要费点心思的。
全文完!
我的其他文章:
- 1 阿里云平台OSS对象存储
- 2 Dubbo学习系列之十七(微服务Soul网关)
- 3 Docker部署RocketMQ
- 4 流式计算(五)-Flink 计算模型
- 5 流式计算(四)-Flink Stream API 篇二
只写原创,敬请关注
H5开发移动应用APP(店铺系列一)的更多相关文章
- Anyoffice -HTML5大赛 悦心(基于H5开发安卓音乐app)-项目总结
项目在线演示地址:http://rose111.applinzi.com/ github 地址:欢迎star https://github.com/midoxinxin/YueX-Music 悦心,一 ...
- MUI框架开发HTML5手机APP(一)--搭建第一个手机APP
前 言 JRedu 随着HTML5的不断发展,移动开发成为主流趋势!越来越多的公司开始选择使用HTML5开发手机APP,而随着手机硬件设备配置的不断提升,各种开发框架的不断优化,也使着H5开发的 ...
- MUI框架开发HTML5手机APP(一)--搭建第一个手机APP(转)
出处:http://www.cnblogs.com/jerehedu/p/7832808.html 前 言 JRedu 随着HTML5的不断发展,移动开发成为主流趋势!越来越多的公司开始选择使用H ...
- MUI框架开发HTML5手机APP
出处:http://www.cnblogs.com/jerehedu/p/7832808.html 前 言 JRedu 随着HTML5的不断发展,移动开发成为主流趋势!越来越多的公司开始选择使用H ...
- 原生开发、H5开发、混合移动开发的优缺点
一.原生开发(Native App开发) 原生开发,是在Android.IOS等移动平台上利用官方提供的开发语言.开发类库.开发工具进行App开发.比如Android是利用Java.Eclipse.A ...
- 关于APP,原生和H5开发技术的争论
App的开发技术,目前流行的两种方式,原生和Html5.原生分了安卓平台和ios平台(还有小众的黑莓.死去的塞班就不说了),H5就是Html5. 目前争论不休的问题,在早先前争论CS,BS架构的软件系 ...
- H5外包团队 H5开发微信APP的优势有哪些
H5外包团队 H5开发微信APP的优势有哪些
- 用H5开发微信还是开发APP?
用H5开发微信还是开发APP? 随着技术的飞速发展,HTML第五版技术标准的更新,在移动端,由于其相对较低的开发成本及强大的跨平台运行能力,越来越多的信息型产品也开始选择这样轻量级的H5页面进行快速迭 ...
- 关于APP,原生和H5开发技术的争论 APP开发技术选型判断依据
关于APP,原生和H5开发技术的争论 App的开发技术,目前流行的两种方式,原生和Html5.原生分了安卓平台和ios平台(还有小众的黑莓.死去的塞班就不说了),H5就是Html5. 目前争论不休的问 ...
随机推荐
- logback日志大量写磁盘导致微服务不能正常响应的解决方案
最近几天,遇到一个莫名其妙的问题,每天几乎同一时段微服务自己跑着跑着就假死了,过几个小时就又自动恢复了. 通过对定时任务.网卡.内存.磁盘.业务日志的排查分析,只有磁盘的IO在假死前一段时间偏高,经查 ...
- android ijkplayer简单使用
class VideoPlayer : FrameLayout, TextureView.SurfaceTextureListener{ private var url:String? = null ...
- [LC] 15. 3Sum
Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find ...
- Mate20 pro实现H265 (HEVC)实时硬件编码
谁能告诉我手机上用H265实时编码有什么鸟用? 一.先看看手机支持哪些codec ALL_CODECS REGULAR_CODECS mine-type 选择mime-type为video/hevc, ...
- Mysql分区,分库和分表
作者说的非常清楚了,感谢.地址为:http://haitian299.github.io/2016/05/26/mysql-partitioning/. 本人项目实践,使用sharding-jdbc进 ...
- [LC] 303. Range Sum Query - Immutable
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...
- [Python] Advanced features
Slicing 12345 L[:10:2] # [0, 2, 4, 6, 8]L[::5] # 所有数,每5个取一个# [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, ...
- getcwd() 和 os.path.realpath () 的区别
http://lemfix.com/topics/7 getcwd()获取当前目录:其他文件调用时,会根据当前文件的位置获取目录,不同的文件调用,值是不一样的. os.path.realpath()获 ...
- 押宝在Apple Watch的智能手表游戏玩得转吗?
Watch的智能手表游戏玩得转吗?" title="押宝在Apple Watch的智能手表游戏玩得转吗?"> 如果你给法拉利跑车贴上金箔,会被认为是俗气.但若在Ap ...
- 0-1背包问题-DP
中文理解: 0-1背包问题:有一个贼在偷窃一家商店时,发现有n件物品,第i件物品价值vi元,重wi磅,此处vi与wi都是整数.他希望带走的东西越值钱越好,但他的背包中至多只能装下W磅的东西,W为一整数 ...