亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 課堂 > 小程序 > 正文

小程序分頁實踐之編寫可復用分頁組件

2020-03-21 15:51:20
字體:
來源:轉載
供稿:網友

項目中遇到 tab切換列表,每個tab都需要分頁的需求,分頁流程具有相似性,于是想將分頁封裝為組件,方便應用。

組件的應用已寫成一個小demo,效果如下圖所示(數據用mock模擬):

小程序,分頁,分頁組件

源碼可以查看:wxapp-pagination

項目需求

具體項目需求:

  • 查看自己相關的會議(頁面命名為 meetings)
  • tab切換,分為:
    • “我的會議”(我參加的會議,后面會以 "join" 為 key區分)
    • “我的預約”(我預約的會議,后面會以 "book" 為 key區分)
  • 一次加載10條(size=10),拉到底部后,加載下一頁(page = page +1)

當然,作為前端,要考慮性能方面的需求:

  • 首次只加載默認tab頁的首頁,其他tab等到點擊到對應tab才開始加載。
  • 回到已加載過的tab頁,保留原數據不重新加載。

所以原型圖大概就長這樣:

小程序,分頁,分頁組件

邏輯實現

與分頁邏輯相關的項目結構如下:

├── components│    ├── meeting-item   # 列表item│    └── pagination      # 分頁組件├── model│  └── user.js          # 我的相關 model└── pages│    └── user            # 我的相關頁面│    ├── meetings    # 我的會議(就是tab要分頁的頁面啦)│    └── ...│└── vant-weapp

還是用圖理一下他們之間的關系吧:

小程序,分頁,分頁組件

在組件內監聽觸發分頁事件

觸發分頁的事件是滾動到頁面的底部,小程序中,觸發該事件是Page頁面的onReachBottom事件,但是這個事件只能在Page中觸發,所以要將這個觸發時機傳遞給pagination組件。

解決思路是:組件 pagination 內,設置key屬性,每當onReachBottom事件觸發之后,設置組件屬性 key  為一個隨機字符串,當組件 pagination 監聽到key的變化的時候,做出分頁操作。

// components/pagination/index.jsComponent({ properties: {  key: {   type: String,   observer: '_loadMoreData' // _loadMoreData 為分頁操作  } }})
<!-- pages/user/meetings/index.wxml --><tabs active="{{currentTab}}" bind:change="onChange">  <tab   <view class="meeting-list">     <pagination       name="JOIN"      key="{{joinKey}}"      >     </pagination>   </view>  </tab>  <tab   <view class="meeting-list">    <pagination      name="BOOK"     key="{{bookKey}}"    >    </pagination>   </view>  </tab></tabs>
Page({ onReachBottom(){  const key = scene[+this.data.currentTab].key // 對應tab對應key  this.setData({   [key]: random(16)  }) }})

分頁組件的實現邏輯

觸發到達底部之后,需要加載數據。但再加載之前,先滿足加載的條件:

  • 上一頁還未加載完成(loading = true),不重復加載
  • 當前頁面全部加載完(ended = true),不繼續加載

具體加載流程為:

  1. page:觸發 onReachBottom 事件,修改 pagination組件 key 值
  2. component: key值監聽到變化,觸發加載事件 _loadMoreData
  3. component: _loadMoreData 中判斷滿足條件后,觸發加載列表函數 this.triggerEvent('getList'),并傳入頁面參數page 和 size。
  4. page:向model層獲取數據。
  5. page:獲取數據后,傳遞給 pagination組件list和total 值。
  6. component:list 監聽到變化,判斷是否加載完成。

component

// components/pagination/index.jsComponent({ properties: {  name: String,  key: {   type: String,   observer: '_loadMoreData' // _loadMoreData 為分頁操作  },  size: { // 每次加載條目數   type: Number,   value: 10  },  total: Number, // 頁面總數  list: {         // 已加載條目   type: Array,   observer: '_endState'   // 每次加載完新數據,判斷數據是否全部加載完成  } }, data: {  page: 0,        // 當前第幾頁  loading: false, // 是否正在加載  ended: false  // 數據是否已全部加載完成 },  methods: {  _loadMoreData(){   const { loading, ended, size } = this.data   if (loading) return // 上一頁還未加載完成,不加載   if (ended) return  // 當前頁面全部加載完,不加載   const page = this.data.page + 1   this.setData({    loading: true, // 開始加載新頁面loading設置為true    page   })   // 觸發加載下一頁,并傳入參數   this.triggerEvent('getList', {    page,    size   })  },  _endState(val, oldVal) {   const { total, list } = this.properties   let ended = false   // 判斷數據是否全部加載完成   if (list.length >= total) {    ended = true   }   this.setData({    loading: false, // 當前頁面加載完成,loading設置為false    ended   })  } }})

page

<!-- pages/user/meetings/index.wxml --><pagination  name="BOOK" key="{{bookKey}}" bind:getList="getBookMeetings" list="{{bookMeetings}}" total="{{bookTotal}}"></pagination>

循環列表item

pagination組件獲取了可循環的列表,初始想法是循環slot,但是在slot中卻獲取不到 item 對象:

<view wx:for="{{list}}" wx:for-item="item" wx:key="index"> <slot></slot></view>

解決的辦法是將每個列表項封裝為組件,循環抽象節點,這樣對其他頁面的分頁具有可拓展性。

componentGenerics 字段中聲明:

// components/pagination/index.json{ "componentGenerics": {  "selectable": true }, // ...}

使用抽象節點:

<!-- components/pagination/index.wxml --><view wx:for="{{list}}" wx:for-item="item" wx:key="index">  <selectable item="{{item}}"></selectable></view>

指定“selectable”具體是哪個組件:

<!-- pages/user/meetings/index.wxml --><pagination  generic:selectable="meeting-item"  // ... 其他屬性></pagination>

對應 json 文件定義對應 usingComponents :

// pages/user/meetings/index.json{ "usingComponents": {  "pagination":"/components/pagination/index",  "meeting-item":"/components/meeting-item/index" }}

meeting-item 組件接收一個屬性 item,這樣在 meeting-item 組件中,就可以獲取到循環列表的item值,并正常繪制頁面。

實現切換懶加載

給pagination添加initImmediately屬性,當initImmediately為true時,首次加載頁面,并用變量 initState標記是否已經初始化頁面過。

// components/pagination/index.jsComponent({ properties: {  initImmediately: {   type: Boolean,   value: true,   observer: function(val){    if (val && !this.data.initState) {     this.initData()    }   }  },  // ... }, data: {   initState: false, // 是否已經加載過   // ... }, lifetimes: {  attached: function () {   if (this.data.initImmediately){    this.initData()   }  }, }, methods: {  initData(){   console.info(`${this.data.name}:start init data`)   this._loadMoreData()   this.setData({    initState: true   })     },  // ...    _endState(val, oldVal) {   if (!this.data.initState) return    // ...   }, }})

當currentTab為當前類型的時候,initImmediately 設置為 true。

<!-- pages/user/meetings/index.wxml --><pagination   name="JOIN"  init-immediately="{{currentTab==type['JOIN']}}"  // ...></pagination><pagination   name="BOOK"  init-immediately="{{currentTab==type['BOOK']}}"  // ...></pagination>

組件的復用

完成了以上組件,在對其他分頁的頁面,可以直接復用。比如,實現一個獲取全部用戶列表的分頁,只需要新增一個user-item的組件,像這樣調用:

<pagination  name="USER" key="{{key}}"  bind:getList="getUserList"  list="{{userList}}"  total="{{userTotal}}" generic:selectable="user-item"></pagination>

具體應用可以查看我寫的小demo:wxapp-pagination。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产亚洲视频在线观看| 日韩成人高清在线| 日本三级久久久| 亚洲成人999| 日韩在线免费av| 国产69精品久久久久99| 日韩免费观看网站| 色偷偷噜噜噜亚洲男人| 91亚洲va在线va天堂va国| 国产精品美女在线观看| 久久这里有精品视频| 一个人看的www久久| 色天天综合狠狠色| 97在线视频免费播放| 国产日韩中文字幕| 97视频国产在线| 亚洲天堂久久av| 91精品国产91| 欧美成人高清视频| 欧美色道久久88综合亚洲精品| 亚洲精品视频免费在线观看| 国产精品自产拍高潮在线观看| 美女啪啪无遮挡免费久久网站| 性欧美在线看片a免费观看| 亚洲精品有码在线| 97国产在线观看| 精品国内亚洲在观看18黄| 亚洲日本中文字幕| 国产精品第七影院| 亚洲精品欧美一区二区三区| 国产精品专区第二| 国产欧美精品在线播放| 亚洲欧美国产日韩天堂区| 亚洲福利小视频| 欧美另类老女人| 日韩免费在线看| 国产精品盗摄久久久| 日韩免费在线免费观看| 国产欧洲精品视频| 日韩中文字幕在线播放| 亚洲国产另类 国产精品国产免费| 亚洲国产精品电影在线观看| 国产一区二区三区视频在线观看| 日韩福利视频在线观看| 久热99视频在线观看| 国产69精品久久久久99| 国产精品三级网站| 日韩av免费看网站| 亚洲色图欧美制服丝袜另类第一页| 国产一区二区三区视频免费| 欧美激情精品久久久久久久变态| 2019亚洲男人天堂| 亚洲成人黄色在线| 亚洲视频欧美视频| 精品五月天久久| 欧美在线视频一区二区| 亚洲精品免费在线视频| 日韩av在线网页| 精品国产精品自拍| 国产亚洲精品综合一区91| 日韩大陆欧美高清视频区| 国产a∨精品一区二区三区不卡| 欧美日韩中文字幕| 91九色综合久久| 成人有码在线视频| 97av在线影院| 97久久精品人搡人人玩| 精品国产一区二区三区四区在线观看| 亚洲国内精品在线| 欧美一区二区三区四区在线| 国产日本欧美一区二区三区| 国产精品久久久久久av| 成人精品视频99在线观看免费| 国产成人精品免高潮在线观看| 91av视频在线免费观看| 日韩在线观看电影| 中文字幕在线成人| 亚洲精品国产美女| 欧洲精品在线视频| 91人人爽人人爽人人精88v| 亚洲午夜激情免费视频| 91精品国产综合久久香蕉最新版| 欧美性猛交xxxx黑人猛交| 日本欧美爱爱爱| 热久久这里只有精品| 国产91精品视频在线观看| 日韩中文综合网| 97在线免费观看视频| 91av视频在线| 欧美性感美女h网站在线观看免费| 日韩av片电影专区| 国产91色在线播放| 亚洲xxx自由成熟| 亚洲电影免费观看高清| 亚洲欧洲av一区二区| 国产成人涩涩涩视频在线观看| 日本高清久久天堂| 久久国产精品久久久久| 在线观看国产精品日韩av| 91久久综合亚洲鲁鲁五月天| 亚洲美女免费精品视频在线观看| 久久精品久久久久久国产 免费| 成人黄色影片在线| 欧美亚洲日本网站| 亚洲成人精品视频在线观看| 91国产在线精品| 亚洲美女在线视频| 日韩欧美a级成人黄色| 午夜欧美不卡精品aaaaa| 韩国三级日本三级少妇99| 色偷偷888欧美精品久久久| 日韩av电影国产| 国产精品免费观看在线| 久久在线免费观看视频| 精品国产乱码久久久久久虫虫漫画| 中文字幕av一区二区三区谷原希美| www.日韩视频| 国产精品自拍小视频| 亚洲高清色综合| www亚洲精品| 亚洲欧美日韩中文在线制服| 日韩高清免费在线| 久久久久亚洲精品国产| 午夜精品美女自拍福到在线| 亚洲一区二区三区成人在线视频精品| 亚洲一区二区三区四区在线播放| 国产精品黄视频| 日韩国产一区三区| 国产日韩欧美在线| 亚洲第一区中文字幕| 亚洲人成电影在线播放| 亚洲第一区中文99精品| 亚洲精品在线不卡| 欧美极品美女视频网站在线观看免费| 在线观看国产精品91| 亚洲精品免费一区二区三区| 亚洲自拍偷拍色片视频| 国产精品自在线| 日韩国产激情在线| 国产成人一区二区| 成人免费福利视频| 亚洲黄页视频免费观看| 日韩欧美在线观看| 国内精品久久久久久影视8| 国产91免费观看| 国产精品美女午夜av| 久久久之久亚州精品露出| 亚洲欧美国产视频| 成人乱人伦精品视频在线观看| 亚洲欧洲第一视频| 国产成人av在线| 亚洲另类欧美自拍| 国产成人精品视频| 92版电视剧仙鹤神针在线观看| 日本精品一区二区三区在线播放视频| 日韩av在线网址| 亚洲老司机av| 欧美激情精品久久久久久变态| 欧美亚洲国产精品| 国产日韩在线亚洲字幕中文| 欧美亚洲国产精品| 亚洲色图综合久久| 久久精品国产2020观看福利| 欧美一区二粉嫩精品国产一线天|