uni-app | 上拉加載和下拉刷新探索

https://juejin.im/post/5e49ec81e51d4527196d4c08前端


Vue 生態 - 多端解決方案 uni-app

我的練手項目《某瓣電影 APP》vue

列表頁上拉加載更多,下拉刷新效果

輕鬆實現上拉加載、下拉刷新、返回頂部git

實現效果github

demo.gif

前期準備

後端接口

在這個小案例中,咱們採用開源的jsonplaceholder,這也是咱們前端經常使用的測試接口。爲了達到小 demo 的效果暫且使用這個,後續替換爲 douban-apijson

甚至咱們都不用mock接口,同時最重要的一點是支持分頁查詢,查詢的參數是小程序

  • offset
  • limit

寫事後臺的應該對這兩個字段不陌生,offset偏移量的意思,這個在nest官網也有提到後端

{
    "page":1,
    "limit":10
}
複製代碼

在請求的時候相似是這種,傳的頁面的信息,不過咱們輸入的參數api

{
    "_offset":xx, // 其中xx 表明的是第幾頁
    "_limit":xx  // 其中xx 表明的是每頁多少條數據
}
複製代碼

下面咱們在瀏覽器地址欄輸入(或者使用 postman|postwoman|Vscode 的插件均可) https://jsonplaceholder.typicode.com/posts數組

返回的結果是:瀏覽器

[
  {
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  },
  {
    "userId": 1,
    "id": 2,
    "title": "qui est esse",
    "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
  },
  {
    "userId": 1,
    "id": 3,
    "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
    "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut"
  }
]
……
複製代碼

那咱們在作上拉加載更多最重要的是,頁碼 發生變化,每次

_offset++;
複製代碼

uni-app 網絡請求 API

在官網上明確指出咱們能夠經過uni.request(OBJECT),其中傳入一個配置對象,值得一提的是默認是GET請求

uni.request({
  url: "https://jsonplaceholder.typicode.com/posts", //請求的地址

  success: res => {
    console.log(res);
  }
});
複製代碼

Item 項

咱們知道在前端的開發中,根據後臺的list循環生成item項是十分常見的業務需求,那麼隨之而來的就是上拉加載更多下拉刷新。那麼在這個小的案例中,我們採用卡片佈局。推薦給你們官方在維護的hello-uniapp

  • github 傳送,其中維護了有不少常見的效果。這裏咱們儘可能clone最新的代碼,由於它仍是更新很頻繁的,主要是爲了解決一些在不一樣設備的bug

20200216125554.png

Do it

  • 異步獲取數據
// 異步獲取列表數據
getDataList() {
    uni.request({
        url: 'https://jsonplaceholder.typicode.com/posts', //僅爲示例,並不是真實接口地址。

        success: (res) => {
                console.log(res)
        }
    });
},
複製代碼

20200216141516.png

那這樣的話是把全部的數據所有獲取來,這在實際開發中是不符合規範的

  • 引入插件

通常咱們期待在列表數據循環的時候,會有一個下拉刷新以及下拉加載最好還能有回到頂部的效果,這個時候咱們採起一個第三方的庫,筆者以爲仍是十分好用

精緻的下拉刷新和上拉加載 js 框架.支持 vue,完美運行於移動端和主流 PC 瀏覽器 star 數目前是2.8K

它也是能夠使用在其餘的開發方案中,固然了也是有uniapp的版本,在使用以前,咱們先來看一段結構佈局部分

<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption" >
		 <view v-for="(item,index) in dataList" :key="`item${index}`">  </view>
	 </mescroll-body>

複製代碼

其中

屬性或方法 含義
ref="mescrollRef" 字節跳動小程序 ref="mescrollRef" 必須配置
@init="mescrollInit" 必須配置
@down="downCallback" 必須配置
@up="upCallback" 必須配置
:down="downOption" 下拉刷新的經常使用配置
:up="upOption" 上拉加載的經常使用配置

因爲咱們在一個項目的不少地方都須要使用到這個效果,那麼咱們索性,全局引入,註冊爲全局組件

// 在main.js註冊全局組件
import MescrollBody from "@/components/mescroll-uni/mescroll-body.vue";
import MescrollUni from "@/components/mescroll-uni/mescroll-uni.vue";
Vue.component("mescroll-body", MescrollBody);
Vue.component("mescroll-uni", MescrollUni);
複製代碼
  • pages.json 配置
{
		"path": "pages/findMovie/findMovie",
		"style": {
			"navigationBarTitleText": "找片",
			"enablePullDownRefresh": false,
			"app-plus": {
				"bounce": "none" //刪除此項: mescroll-body支持iOS回彈
			}
		}
	},
複製代碼

其中有兩個核心的方法

方法 含義
upCallback(page) 上拉加載的回調
downCallback() 下拉刷新的回調

在進行下邊部分以前,咱們須要知道接口返回的數據的總頁數怎麼算,也就是說,在接口返回的數據,通常狀況下會返回一個total

Math.ceil(5 / 2);
Math.ceil(26 / 10);
Math.ceil(100 / 10);
Math.ceil(20 / 4);
複製代碼

20200216162252.png

  • 核心代碼
/*上拉加載的回調*/
upCallback({num,size}) {
// console.log(num,size) // 1,10
uni.request({
    url: `https://jsonplaceholder.typicode.com/posts`,
    data: {
        _offset: num,
        _limit: size
    },
    success: (data) => {
        // 接口返回的當前頁數據列表 (數組)
        let curPageData = data.data;
        // 接口返回的當前頁數據長度 (如列表有26個數據,當前頁返回8個,則curPageLen=8)
        let curPageLen = data.data.length;
        // 接口返回的總頁數 (如列表有26個數據,每頁10條,共3頁; 則totalPage=3)
        let totalPage = Math.ceil(100/size); // 向上取正
        // 接口返回的總數據量(如列表有26個數據,每頁10條,共3頁; 則totalSize=26)
        let totalSize = 100;
        // 接口返回的是否有下一頁 (true/false)
        // let hasNext = data.xxx;

        //設置列表數據
        if (this.mescroll.num == 1) this.dataList = []; //若是是第一頁需手動置空列表
        this.dataList = this.dataList.concat(curPageData); //追加新數據

        // 請求成功,隱藏加載狀態
        //方法一(推薦): 後臺接口有返回列表的總頁數 totalPage
        this.mescroll.endByPage(curPageLen, totalPage);

        //方法二(推薦): 後臺接口有返回列表的總數據量 totalSize
        //this.mescroll.endBySize(curPageLen, totalSize);

        //方法三(推薦): 您有其餘方式知道是否有下一頁 hasNext
        //this.mescroll.endSuccess(curPageLen, hasNext);
    },
    fail: () => {
        // 請求失敗,隱藏加載狀態
        this.mescroll.endErr()
    }
})
},
複製代碼

寫在最後

關於uniapp-douban-movie 這個項目是筆者持續更新維護的一份基於 Vue 生態的多終端解決方案uniapp的我的練手項目,一些在實際開發中遇到的需求會在這個小項目梳理 有幾點特性

  • 更新時間不肯定
  • 代碼會同步 github
  • 儘量模仿豆瓣電影的UI

模塊

效果名字 其餘
項目中,列表頁上拉加載更多,下拉刷新效果

若是感受挺好玩,不妨給個星星 代碼同步在這裏


Although it is over, thank you

相關文章
相關標籤/搜索