W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
小程序長列表組件
使用此組件需要依賴小程序基礎(chǔ)庫 2.2.2 版本,同時依賴開發(fā)者工具的 npm 構(gòu)建。具體詳情可查閱官方 npm 文檔。
?目前小程序會有不少的應(yīng)用場景里會用到無限長列表的交互,當一個頁面展示很多信息的時候,會造成小程序頁面的卡頓以及白屏。原因有如下幾點:
因此就有長列表組件來解決這些問題。
?核心的思路是只渲染顯示在屏幕的數(shù)據(jù),基本實現(xiàn)就是監(jiān)聽 scroll 事件,并且重新計算需要渲染的數(shù)據(jù),不需要渲染的數(shù)據(jù)留一個空的 div 占位元素。
假設(shè)列表數(shù)據(jù)有100個 item,知道了滾動的位置,怎么知道哪些 item 必須顯示在頁面?因為 item 還沒渲染出來,不能通過 getComputedStyle 等 DOM 操作得到每個 item 的位置,所以無法知道哪些 item 需要渲染。為了解決這個問題,需要每個 item 固定寬高。item 的寬高的定義見下面的 API 的createRecycleContext()的參數(shù) itemSize 的介紹。
滾動過程中,重新渲染數(shù)據(jù)的同時,需要設(shè)置當前數(shù)據(jù)的前后的 div 占位元素高度,同時是指在同一個渲染周期內(nèi)。頁面渲染是通過 setData 觸發(fā)的,列表數(shù)據(jù)和 div 占位高度在2個組件內(nèi)進行 setData 的,為了把這2個 setData 放在同一個渲染周期,用了一個 hack 方法,所以定義 recycle-view 的 batch 屬性固定為 batch="{{batchSetRecycleData}}"。
在滾動過程中,為了避免頻繁出現(xiàn)白屏,會多渲染當前屏幕的前后2個屏幕的內(nèi)容。
長列表組件由2個自定義組件 recycle-view、recycle-item 和一組 API 組成,對應(yīng)的代碼結(jié)構(gòu)如下
├── miniprogram-recycle-view/
└── recycle-view 組件
└── recycle-item 組件
└── index.js
包結(jié)構(gòu)詳細描述如下:
目錄/文件 | 描述 |
---|---|
recycle-view 組件 | 長列表組件 |
recycle-item 組件 | 長列表每一項 item 組件 |
index.js | 提供操作長列表數(shù)據(jù)的API |
1.安裝組件
npm install --save miniprogram-recycle-view
2.在頁面的 json 配置文件中添加 recycle-view 和 recycle-item 自定義組件的配置
{
"usingComponents": {
"recycle-view": "miniprogram-recycle-view/recycle-view",
"recycle-item": "miniprogram-recycle-view/recycle-item"
}
}
3.WXML 文件中引用 recycle-view
<recycle-view batch="{{batchSetRecycleData}}" id="recycleId">
<view slot="before">長列表前面的內(nèi)容</view>
<recycle-item wx:for="{{recycleList}}" wx:key="id">
<view>
<image style='width:80px;height:80px;float:left;' src="{{item.image_url}}"></image>
{{item.idx+1}}. {{item.title}}
</view>
</recycle-item>
<view slot="after">長列表后面的內(nèi)容</view>
</recycle-view>
recycle-view 的屬性介紹如下:
字段名 | 類型 | 必填 | 描述 |
---|---|---|---|
id | String | 是 | id必須是頁面唯一的字符串 |
batch | Boolean | 是 | 必須設(shè)置為{{batchSetRecycleData}} 才能生效 |
height | Number | 否 | 設(shè)置recycle-view的高度,默認為頁面高度 |
width | Number | 否 | 設(shè)置recycle-view的寬度,默認是頁面的寬度 |
enable-back-to-top | Boolean | 否 | 默認為false,同scroll-view同名字段 |
scroll-top | Number | 否 | 默認為false,同scroll-view同名字段 |
scroll-y | Number | 否 | 默認為true,同scroll-view同名字段 |
scroll-to-index | Number | 否 | 設(shè)置滾動到長列表的項 |
placeholder-image | String | 否 | 默認占位背景圖片,在渲染不及時的時候顯示,不建議使用大圖作為占位。建議傳入SVG的Base64格式,可使用工具將SVG代碼轉(zhuǎn)為Base64格式。支持SVG中設(shè)置rpx。 |
scroll-with-animation | Boolean | 否 | 默認為false,同scroll-view的同名字段 |
lower-threshold | Number | 否 | 默認為false,同scroll-view同名字段 |
upper-threshold | Number | 否 | 默認為false,同scroll-view同名字段 |
bindscroll | 事件 | 否 | 同scroll-view同名字段 |
bindscrolltolower | 事件 | 否 | 同scroll-view同名字段 |
bindscrolltoupper | 事件 | 否 | 同scroll-view同名字段 |
recycle-view 包含3個 slot,具體介紹如下:
名稱 | 描述 |
---|---|
before | 默認 slot 的前面的非回收區(qū)域 |
默認 slot | 長列表的列表展示區(qū)域,recycle-item 必須定義在默認 slot 中 |
after | 默認 slot 的后面的非回收區(qū)域 |
長列表的內(nèi)容實際是在一個 scroll-view 滾動區(qū)域里面的,當長列表里面的內(nèi)容,不止是單獨的一個列表的時候,例如我們頁面底部都會有一個 copyright 的聲明,我們就可以把這部分的內(nèi)容放在 before 和 after 這2個 slot 里面。
recycle-item 的介紹如下:
需要注意的是,recycle-item 中必須定義 wx:for 列表循環(huán),不應(yīng)該通過 setData 來設(shè)置 wx:for 綁定的變量,而是通過createRecycleContext方法創(chuàng)建RecycleContext對象來管理數(shù)據(jù),createRecycleContext在 index.js 文件里面定義。建議同時設(shè)置 wx:key,以提升列表的渲染性能。
4.頁面 JS 管理 recycle-view 的數(shù)據(jù)
const createRecycleContext = require('miniprogram-recycle-view')
Page({
onReady: function() {
var ctx = createRecycleContext({
id: 'recycleId',
dataKey: 'recycleList',
page: this,
itemSize: { // 這個參數(shù)也可以直接傳下面定義的this.itemSizeFunc函數(shù)
width: 162,
height: 182
}
})
ctx.append(newList)
// ctx.update(beginIndex, list)
// ctx.destroy()
},
itemSizeFunc: function (item, idx) {
return {
width: 162,
height: 182
}
}
})
頁面必須通過 Component 構(gòu)造器定義,頁面引入了miniprogram-recycle-view包之后,會在 wx 對象下面新增接口createRecycleContext函數(shù)創(chuàng)建RecycleContext對象來管理 recycle-view 定義的的數(shù)據(jù),createRecycleContext接收類型為1個 Object 的參數(shù),Object 參數(shù)的每一個 key 的介紹如下:
參數(shù)名 | 類型 | 描述 |
---|---|---|
id | String | 對應(yīng) recycle-view 的 id 屬性的值 |
dataKey | String | 對應(yīng) recycle-item 的 wx:for 屬性設(shè)置的綁定變量名 |
page | Page/Component | recycle-view 所在的頁面或者組件的實例,頁面或者組件內(nèi)可以直接傳 this |
itemSize | Object/Function | 此參數(shù)用來生成recycle-item的寬和高,前面提到過,要知道當前需要渲染哪些item,必須知道item的寬高才能進行計算 Object必須包含{width, height}兩個屬性,F(xiàn)unction的話接收item, index這2個參數(shù),返回一個包含{width, height}的Object itemSize如果是函數(shù),函數(shù)里面 this 指向RecycleContext如果樣式使用了rpx,可以通過transformRpx來轉(zhuǎn)化為px。 為Object類型的時候,還有另外一種用法,詳細情況見下面的itemSize章節(jié)的介紹。 |
useInPage | Boolean | 是否整個頁面只有recycle-view。Page的定義里面必須至少加空的onPageScroll函數(shù),主要是用在頁面級別的長列表,并且需要用到onPullDownRefresh的效果。切必須設(shè)置root 參數(shù)為當前頁面對象 |
root | Page | 當前頁面對象,可以通過getCurrentPages獲取, 當useInPage為true必須提供 |
RecycleContext 對象提供的方法有:
方法 | 參數(shù) | 說明 |
---|---|---|
append | list, callback | 在當前的長列表數(shù)據(jù)上追加list數(shù)據(jù),callback是渲染完成的回調(diào)函數(shù) |
splice | begin, count, list, callback | 插入/刪除長列表數(shù)據(jù),參數(shù)同Array的splice函數(shù),callback是渲染完成的回調(diào)函數(shù) |
update | begin, list, callback | 更新長列表的數(shù)據(jù),從索引參數(shù)begin開始,更新為參數(shù)list,參數(shù)callback同splice。 |
destroy | 無 | 銷毀RecycleContext對象,在recycle-view銷毀的時候調(diào)用此方法 |
forceUpdate | callback, reinitSlot | 重新渲染recycle-view。callback是渲染完成的回調(diào)函數(shù),當before和after這2個slot的高度發(fā)生變化時候調(diào)用此函數(shù),reinitSlot設(shè)置為true。當item的寬高發(fā)生變化的時候也需要調(diào)用此方法。 |
getBoundingClientRect | index | 獲取某個數(shù)據(jù)項的在長列表中的位置,返回{left, top, width, height}的Object。 |
getScrollTop | 無 | 獲取長列表的當前的滾動位置。 |
transformRpx | rpx | 將rpx轉(zhuǎn)化為px,返回轉(zhuǎn)化后的px整數(shù)。itemSize返回的寬高單位是px,可以在這里調(diào)用此函數(shù)將rpx轉(zhuǎn)化為px,參數(shù)是Number,例如ctx.transformRpx(140),返回70。注意,transformRpx會進行四舍五入,所以transformRpx(20) + transformRpx(90)不一定等于transformRpx(110) |
getViewportItems | inViewportPx | 獲取在視窗內(nèi)的數(shù)據(jù)項,用于判斷某個項是否出現(xiàn)在視窗內(nèi)。用于曝光數(shù)據(jù)上報,菜品和類別的聯(lián)動效果實現(xiàn)。參數(shù)inViewportPx表示距離屏幕多少像素為出現(xiàn)在屏幕內(nèi),可以為負值。 |
其中 itemSize 的使用
itemSize可以為包含{width, height}的Object,所有數(shù)據(jù)只有一種寬高信息。如果有多種,則可以提供一個函數(shù),長列表組件會調(diào)用這個函數(shù)生成每條數(shù)據(jù)的寬高信息,如下所示:
function(item, index) {
return {
width: 195,
height: item.azFirst ? 130 : 120
}
}
<recycle-view batch="{{batchSetRecycleData}}" batch-key="batchSetRecycleData"></recycle-view>
<recycle-view batch="{{batchSetRecycleData1}}" batch-key="batchSetRecycleData1"></recycle-view>
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: