最佳方式實(shí)現(xiàn)微信小程序分頁加載數(shù)據(jù)

一般小程序做分頁加載數(shù)據(jù)裳仆,會做一些下拉加載更多、然后上拉刷新的操作孤钦。數(shù)據(jù)放在一個(gè)for循環(huán)里去加載歧斟,數(shù)據(jù)源是一個(gè)數(shù)組對象纯丸。在加載下一頁數(shù)據(jù)時(shí),將下一頁的數(shù)據(jù)拼到當(dāng)前數(shù)組后面静袖。這樣的確可以實(shí)現(xiàn)分頁加載數(shù)據(jù)觉鼻,但是如果數(shù)組中的對象都比較大,那么可能加載個(gè)幾頁數(shù)據(jù)队橙,這個(gè)數(shù)組的大小就超過微信的限制了坠陈。可能會出現(xiàn) VM429:1 appDataChange 數(shù)據(jù)傳輸長度為 1203320 已經(jīng)超過最大長度 1048576 的異常捐康。

下面分別使用普通的方式和另一種方法解決來處理數(shù)據(jù)分頁加載的問題仇矾。完整項(xiàng)目可以在這里下載到

效果

程序運(yùn)行效果
普通方式加載
增強(qiáng)方式加載

說明

這個(gè)項(xiàng)目中用來分頁的數(shù)據(jù)都是請求同一段json數(shù)據(jù),這段json的數(shù)據(jù)結(jié)構(gòu)是我自己拼的吹由,實(shí)際在應(yīng)用中若未,可以根據(jù)自己項(xiàng)目需求來分頁請求數(shù)據(jù)。這段數(shù)據(jù)的結(jié)構(gòu)為一個(gè)data對象倾鲫,data對象對應(yīng)的是一個(gè)對象數(shù)組粗合。數(shù)組中每個(gè)對象都是一篇文章的信息,嗯乌昔,就是高中語文書里都要背的那種隙疚。每頁的數(shù)據(jù)是40條。一段json大小為570K磕道。另外供屉,這個(gè)項(xiàng)目是為了表現(xiàn)兩種數(shù)據(jù)加載方式而設(shè)計(jì)的項(xiàng)目,并不是真實(shí)的項(xiàng)目溺蕉。

{
    "data": [{
            "author": "作者",
            "dynasty": "作者朝代",
            "title": "文章題目",
            "article": "文章的具體內(nèi)容",
            "useless_data": "沒什么用的數(shù)據(jù)伶丐,純粹為了增加數(shù)據(jù)長度,能更快查看到異常的拋出疯特。",
            "share_times": 0,
            "like_times": 0,
            "id": "0"
        }]
}

數(shù)據(jù)加載頁面中的功能簡介

不論是普通加載還是增強(qiáng)加載哗魂,在頁面的onLoad過程中都先調(diào)用了一個(gè) loadInitData的方法,用來獲取第一頁數(shù)據(jù)漓雅。

之后點(diǎn)擊頁面底部的加載更多录别,可以加載下一頁數(shù)據(jù),而加載下一頁數(shù)據(jù)使用的是另一個(gè)方法loadMoreData邻吞。

另外頁面中還可以點(diǎn)擊愛心來增加喜歡次數(shù)likeTap组题、點(diǎn)擊分享來增加分享次數(shù)shareTap,這是模擬向服務(wù)器請求更新數(shù)據(jù)抱冷。點(diǎn)擊作者或文章題目來查看文章的詳細(xì)信息viewDetail崔列。

普通方式分頁加載數(shù)據(jù)

普通、簡單的分頁加載數(shù)據(jù)徘层,是將要展示的數(shù)據(jù)放在一個(gè)數(shù)組中峻呕,通過一個(gè)for循環(huán)將數(shù)據(jù)渲染出來利职。在normalLoading.wxml中趣效,普通加載的模版是這樣的:

<scroll-view scroll-y="true" style = "height:100%;position: relative;" scroll-into-view="{{toView}}" scroll-with-animation = "true">
  <view id = "top"></view>
  <block wx:for="{{articles}}">
    <template is = "articles" data='{{item:item,index:index}}'/> <!--將item和index都傳到模版里去瘦癌,不然模版中獲取不到index-->
  </block>
  <view id = "bottom"></view>
</scroll-view>

加載初始數(shù)據(jù),推薦放在一個(gè)方法中請求跷敬,因?yàn)槿绻鱿吕⑿虏僮鞯脑捬端剑恍枰诔霭l(fā)下拉刷新操作后,再調(diào)用一下這個(gè)方法就可以了西傀。

/**
   * 加載初始數(shù)據(jù),有時(shí)候?yàn)榱颂嵘撁娲蜷_速度斤寇,會將所有數(shù)據(jù)合并到一個(gè)接口中返回,然后列表中的第二頁數(shù)據(jù)開始拥褂,使用其它接口返回娘锁,即分頁獲取數(shù)據(jù)時(shí),僅獲取下一頁的數(shù)據(jù)饺鹃。(這里僅做示例莫秆,因?yàn)槊恳豁摂?shù)據(jù)都取一樣的。在實(shí)際開發(fā)中可以考慮這樣分開悔详。)
   */
  loadInitData: function () {
    var that = this
    var currentPage = 0;
    var tips = "加載第" + (currentPage+1) + "頁";
    console.log("load page " + (currentPage+1));
    wx.showLoading({
      title: tips,
    })
    // 請封裝自己的網(wǎng)絡(luò)請求接口镊屎,這里作為示例就直接使用了wx.request.
    wx.request({
      url: 'https://raw.githubusercontent.com/lanfeng1993/LoadDataDemo/master/data/data.json',
      data: {
      },
      header: {
        'content-type': 'application/json'
      },
      success: function (res) {
        wx.hideLoading();
        var data = res.data; // 接口相應(yīng)的json數(shù)據(jù)
        var articles = data.data; // 接口中的data對應(yīng)了一個(gè)數(shù)組,這里取名為 articles
        console.log(articles);
        that.setData({
          articles: articles,
          currentPage: currentPage
        })
      }
    })

  },

請求下一頁數(shù)據(jù)后茄螃,將本地的數(shù)組和新一頁的數(shù)據(jù)拼接起來缝驳,讓小程序去渲染頁面。

/**
   * 加載下一頁數(shù)據(jù)
   */
  loadMoreData: function () {
    var that = this
    var currentPage = that.data.currentPage; // 獲取當(dāng)前頁碼
    currentPage += 1; // 加載當(dāng)前頁面的下一頁數(shù)據(jù)
    var tips = "加載第" + (currentPage+1) + "頁";
    console.log("load page " + (currentPage+1));
    wx.showLoading({
      title: tips,
    })
    // 請封裝自己的網(wǎng)絡(luò)請求接口归苍,這里作為示例就直接使用了wx.request.
    wx.request({
      url: 'https://raw.githubusercontent.com/lanfeng1993/LoadDataDemo/master/data/data.json',
      data: {
      },
      header: {
        'content-type': 'application/json'
      },
      success: function (res) {
        wx.hideLoading();
        var data = res.data; // 接口相應(yīng)的json數(shù)據(jù)
        var articles = data.data; // 接口中的data對應(yīng)了一個(gè)數(shù)組用狱,這里取名為 articles

        // 將新一頁的數(shù)據(jù)添加到原數(shù)據(jù)后面
        var originArticles = that.data.articles;
        var newArticles = originArticles.concat(articles);
        console.log(newArticles);
        that.setData({
          articles: newArticles,
          currentPage: currentPage
        })
      }
    })
  },

如果項(xiàng)目中的列表數(shù)量是有限、且數(shù)據(jù)簡單且量小的話拼弃,使用這種方式是沒什么問題的夏伊。但是如果數(shù)據(jù)結(jié)構(gòu)非常復(fù)雜,每個(gè)對象序列化成json后肴敛,對象很大署海,這種方式可能就不太適合了,數(shù)據(jù)請求過多甚至?xí)?dǎo)致小程序沒有響應(yīng)医男。

以本項(xiàng)目為例砸狞,數(shù)據(jù)加載到第六頁沙庐,240條數(shù)據(jù)以后秒梅,再加載第七頁的數(shù)據(jù)時(shí),就會拋出VM429:1 appDataChange 數(shù)據(jù)傳輸長度為 1203320 已經(jīng)超過最大長度 1048576的異常隅要,因?yàn)閠hat.setData({}})一次性set的數(shù)據(jù)太大了报账,導(dǎo)致數(shù)據(jù)無法設(shè)置研底。

更好的分頁加載數(shù)據(jù)的方式

相對于上面的加載方式埠偿,只需要在數(shù)據(jù)存儲上做一些小的改變,就能實(shí)現(xiàn)加載更多的數(shù)據(jù)榜晦。這個(gè)方法就是再增加一個(gè)數(shù)組冠蒋,用來存放數(shù)據(jù)。上一個(gè)方法是一個(gè)數(shù)組中存放所有的數(shù)據(jù)乾胶,數(shù)據(jù)量很容易就會變大抖剿。這個(gè)方法,將每一頁請求過來的數(shù)據(jù)的引用放到一個(gè)新的數(shù)組dataArray內(nèi)识窿。dataArray[0]存放第一頁數(shù)據(jù)斩郎,dataArray[1]存儲第二頁數(shù)據(jù)。請求新一頁喻频,都只需要更新一組數(shù)據(jù)缩宜,這樣set的數(shù)據(jù)就不會超過微信小程序允許的長度。這個(gè)方法首先在loadInitData時(shí)甥温,清空dataArray锻煌,防止新數(shù)據(jù)與原數(shù)據(jù)沖突。然后將這一頁數(shù)據(jù)放到dataArray[0]中即可窿侈。

loadInitData: function () {
    var that = this
    var currentPage = 0; // 因?yàn)閿?shù)組下標(biāo)是從0開始的炼幔,所以這里用了0
    var tips = "加載第" + (currentPage+1) + "頁";
    console.log("load page " + (currentPage + 1));
    wx.showLoading({
      title: tips,
    })
    // 刷新時(shí),清空dataArray史简,防止新數(shù)據(jù)與原數(shù)據(jù)沖突
    that.setData({
      dataArray: []
    })
    // 請封裝自己的網(wǎng)絡(luò)請求接口乃秀,這里作為示例就直接使用了wx.request.
    wx.request({
      url: 'https://raw.githubusercontent.com/lanfeng1993/LoadDataDemo/master/data/data.json',
      data: {
      },
      header: {
        'content-type': 'application/json'
      },
      success: function (res) {
        wx.hideLoading();
        var data = res.data; // 接口相應(yīng)的json數(shù)據(jù)
        var articles = data.data; // 接口中的data對應(yīng)了一個(gè)數(shù)組,這里取名為 articles
        var totalDataCount = articles.length;

        // console.log(articles);
        console.log("totalDataCount:"+totalDataCount);
        that.setData({
          ["dataArray["+currentPage+"]"]: articles,
          currentPage: currentPage,
          totalDataCount: totalDataCount
        })
      }
    })

  },

在頁面的渲染上圆兵,與上面的方法也有一些小差別,使用了2個(gè)for循環(huán)來渲染數(shù)據(jù)跺讯。

  <scroll-view scroll-y="true" style = "height:100%;position: relative;" scroll-into-view="{{toView}}" scroll-with-animation = "true">
    <view id = "top"></view>
    <block wx:for="{{dataArray}}" wx:for-item="articles" wx:for-index="dataArrayIndex">
      <block wx:for="{{articles}}" wx:for-item="item" wx:key="{{item.id}}" wx:for-index="index">
        <template is = "articles" data='{{item:item,index:index,dataArrayIndex:dataArrayIndex}}'/> <!--將item和index都傳到模版里去,不然模版中獲取不到index-->
      </block>
    </block>
    <view id = "bottom"></view>
  </scroll-view>

加載下一頁數(shù)據(jù)時(shí)殉农,根據(jù)這頁的下標(biāo)刀脏,將這頁的數(shù)據(jù)放到對應(yīng)下標(biāo)的dataArray中。

/**
   * 加載下一頁數(shù)據(jù)
   */
  loadMoreData: function () {
    var that = this
    var currentPage = that.data.currentPage; // 獲取當(dāng)前頁碼
    currentPage += 1; // 加載當(dāng)前頁面的下一頁數(shù)據(jù)
    var tips = "加載第" + (currentPage + 1) + "頁";
    console.log("load page " + (currentPage + 1));
    wx.showLoading({
      title: tips,
    })
    // 請封裝自己的網(wǎng)絡(luò)請求接口超凳,這里作為示例就直接使用了wx.request.
    wx.request({
      url: 'https://raw.githubusercontent.com/lanfeng1993/LoadDataDemo/master/data/data.json',
      data: {
      },
      header: {
        'content-type': 'application/json'
      },
      success: function (res) {
        wx.hideLoading();
        var data = res.data; // 接口相應(yīng)的json數(shù)據(jù)
        var articles = data.data; // 接口中的data對應(yīng)了一個(gè)數(shù)組愈污,這里取名為 articles

        // 計(jì)算當(dāng)前共加載了多少條數(shù)據(jù),來證明這種方式可以加載更多數(shù)據(jù)
        var totalDataCount = that.data.totalDataCount;
        totalDataCount = totalDataCount + articles.length;
        console.log("totalDataCount:" + totalDataCount);
        
        // 直接將新一頁的數(shù)據(jù)添加到數(shù)組里
        that.setData({
          ["dataArray[" + currentPage + "]"]: articles,
          currentPage: currentPage,
          totalDataCount: totalDataCount
        })
      }
    })
  },

這種方式加載同樣的數(shù)據(jù)可以加載到1400條轮傍,再往下加載會拋出另一個(gè)異常:Uncaught Dom limit exceeded, please check if there's any mistake you've made.這個(gè)問題是因?yàn)樾〕绦蛟谶@個(gè)頁面渲染的dom結(jié)構(gòu)太多了暂雹,已經(jīng)超過了上限,這個(gè)問題目前沒有找到什么解決方法创夜。畢竟數(shù)據(jù)也是不能被無限加載的杭跪,小程序內(nèi)也沒有app中列表的復(fù)用的能力。不過相對于第一種方法,只能加載240條數(shù)據(jù)來說涧尿,這種方法能加載1400條數(shù)據(jù)系奉,也還是可以的,不過加載了1400條數(shù)據(jù)后姑廉,這個(gè)列表滾動(dòng)起來也是非橙绷粒卡了。

總結(jié)

雖然實(shí)際項(xiàng)目中數(shù)據(jù)可能不會加載這么多條數(shù)據(jù)庄蹋,但是因?yàn)檫@里每條數(shù)據(jù)對應(yīng)的對象大小實(shí)際上不算特別大瞬内,實(shí)際項(xiàng)目中的數(shù)據(jù)可能會更復(fù)雜迷雪,更多限书。這時(shí)候,為了性能和速度章咧,可以考慮和后端同學(xué)溝通倦西,將數(shù)據(jù)封裝成一個(gè)結(jié)構(gòu)簡單一些的數(shù)據(jù)傳輸對象,不會直接展示出來的數(shù)據(jù)結(jié)構(gòu)就不要在列表中直接傳輸過來赁严,再結(jié)合第二種方法加載數(shù)據(jù)扰柠,應(yīng)該能應(yīng)對大部分情況了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疼约,一起剝皮案震驚了整個(gè)濱河市卤档,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌程剥,老刑警劉巖劝枣,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異织鲸,居然都是意外死亡舔腾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門搂擦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來稳诚,“玉大人,你說我怎么就攤上這事瀑踢“饣梗” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵橱夭,是天一觀的道長氨距。 經(jīng)常有香客問我,道長徘钥,這世上最難降的妖魔是什么衔蹲? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上舆驶,老公的妹妹穿的比我還像新娘橱健。我一直安慰自己,他們只是感情好沙廉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布拘荡。 她就那樣靜靜地躺著,像睡著了一般撬陵。 火紅的嫁衣襯著肌膚如雪珊皿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天巨税,我揣著相機(jī)與錄音蟋定,去河邊找鬼。 笑死草添,一個(gè)胖子當(dāng)著我的面吹牛驶兜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播远寸,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼抄淑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了驰后?” 一聲冷哼從身側(cè)響起肆资,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎灶芝,沒想到半個(gè)月后郑原,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡监署,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年颤专,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钠乏。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡栖秕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晓避,到底是詐尸還是另有隱情簇捍,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布俏拱,位于F島的核電站暑塑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏锅必。R本人自食惡果不足惜事格,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一惕艳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧驹愚,春花似錦远搪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至劫瞳,卻和暖如春倘潜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背志于。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工涮因, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恨憎。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓蕊退,卻偏偏與公主長得像,于是被迫代替她去往敵國和親憔恳。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1净蚤、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,980評論 3 119
  • 如果有一份新工作钥组,超過你現(xiàn)有工資的20%,你會跳槽嗎今瀑?可能很多小伙伴會猶豫程梦,要不要跳槽。當(dāng)漲薪達(dá)到20%橘荠,已經(jīng)達(dá)到...
    這個(gè)饅頭有餡閱讀 589評論 0 4
  • 此刻剛看完一集電視劇屿附,突然對自己有評判,我怎么可以這么不上進(jìn)哥童,看兒女情仇的電視劇呢挺份?我應(yīng)該做正念練習(xí),應(yīng)該好好的吧...
    水玲瓏英子閱讀 224評論 0 0
  • 致裴莉 卓別林/文 當(dāng)我真正開始愛自己贮懈, 我才認(rèn)識到匀泊,所有的痛苦和情感的折磨, 都只是提醒我: 活著朵你,不要違背自己...
    lilyhuang2050閱讀 238評論 0 0
  • 不知道從何時(shí)起便流行起了“女漢子”這個(gè)詞抡医,從字面意思來看可能你們第一想到的就是像漢子一樣的女人躲因。可我看來并不如此...
    卡特里娜1011閱讀 288評論 0 0