H5開發移動應用APP(店鋪系列一)

首先,這是個真實的案例,我大兄弟在深圳開汽修店鋪,但須要系統來管理平常經營活動,這正不是我擅長的嗎?前端

說幹就幹,直接後端+web端+移動端來一套,因而緊急趕工,起早摸黑,產出約3萬行總量代碼,此係統與工做無關,vue

純屬我的業餘開發,因此我敢拿來任意剖析,若是有時間我就出個連載,作一些典型的技術解析。此次說下移動端開發,ios

考慮到適配和多端問題,還有效率緣由,我選擇了混合模式,即原生作殼,H5+CSS作內容展示,JS代碼實現邏輯,git

而後用第三方工具打包生成移動App,咱們來看下懶加載模式。github

 

準備:web

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

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

 

難度 新手--戰士--老兵--大師後端

目標:數組

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. 不要看上面我只說了不多,這只是核心和思路,具體實現仍是要費點心思的。

全文完!


個人其餘文章:

       

     只寫原創,敬請關注

相關文章
相關標籤/搜索