@mas.io/adc-flat-list v2.0.0
安装
tnpm install --save @alipay/adc-flat-list
组件介绍
能力中心小程序分页加载列表组件,支持长列表优化模式(虚拟滚动),支持下拉刷新、瀑布流等功能 使用限制:需开启基础库2.0
参数说明
属性 | 必填 | 参数类型 | 参数说明 | 默认值 | 示例 |
---|---|---|---|---|---|
list | 是 | Array | 存储列表数据的数组。由使用方管理,并传给组件 | -- | -- |
onFetchData | 是 | Function | 列表数据请求; params:(page: number, limit: number); return: Promise<{ total(数据总数): number, list(数据): Array }>;失败时,请reject | null | -- |
useVirtualScroll | 否 | boolean | 是否开启虚拟滚动 | false | -- |
style | 否 | String | scroll-view容器样式 | 'height:100vh;' | -- |
className | 否 | String | scroll-view容器css类 | '' | -- |
limit | 否 | Number | 分页请求每页条数 | 10 | -- |
loadContent | 否 | ArrayString | 加载时的底部提示 | '马不停蹄加载更多数据中...', '-- 已经到底了,加不了咯 --' | -- |
emptyPageFooter | 否 | Array{text} | 空数据页面,错误处理按钮文案(等同于Page-result组件的footer) | { text: '刷新' } | -- |
id | 否 | String | 如果项目中同时存在多个flat-list组件,并且开启虚拟滚动,需要添加唯一id加以区分 | '' | -- |
pullDownRefresh | 否 | Boolean | 是否开启下拉刷新。开启方法详见下文 | false | -- |
pullDownText | 否 | ArrayString | 下拉刷新时显示的文本 | '下拉刷新', '松开刷新', '刷新成功', '刷新失败' | -- |
autoFetch | 否 | Boolean | 是否在组件didMount时自动调用fetchData。(一般情况不必要使用此参数。如果设为false,则需要手动调用组件ref的fetchData 方法获取数据) | true | -- |
waterfall | 否 | Boolean | Waterfall | 是否开启瀑布流,详见下文 | false | -- |
onTapLeft | 否 | Function | 空数据页面左侧按钮事件(等同于Page-result组件的onTapLeft) | 默认为刷新 | -- |
onTapRight | 否 | Function | 空数据页面左侧按钮事件(等同于Page-result组件的onTapRight) | null | -- |
Slot
Name | 说明 | 是否必传 |
---|---|---|
default | 列表内容 | 否 |
header | 头部内容 | 否 |
empty | 空数据自定义页面 | 否 |
footer | 自定义底部内容。slot-scope有三个属性,isLoading: 是否在加载中, isOver: 是否已是最后一页, page: 最后一页的页码数 | 否 |
组件Ref方法
Name | 说明 |
---|---|
refresh | 刷新列表内容。list的重置需要使用方自己管理 |
在小程序中使用
{
"usingComponents": {
"adc-flat-list": "@alipay/adc-flat-list/es/index"
}
}
在 page.axml 中引用组件
<!-- 页面使用方式 -->
<adc-flat-list
list="{{list}}"
onFetchData="onFetchData">
<test-item
slot-scope="props"
item="{{props.item}}"
index="{{props.index}}">
</test-item>
</adc-flat-list>
useVirtualScroll使用说明
开启虚拟滚动时,必须确保列表数据中有唯一的id字段,因为组件内部会使用a:key="id"。普通模式也推荐有id字段。 虚拟滚动采用的是按页实现,在任何时候,最多会渲染三页的数据。因此应该使每页条数有个合适的值。 支持列表高度不一致的情况。 暂不支持列表高度可以动态改变,和用非分页方式一次渲染全部数据的情况。
scroll-view透传属性
scrollTop, scrollIntoView ,scrollWithAnimation, scrollAnimationDuration, onScroll, upperThreshold, lowerThreshold, onScrollToUpper, onScrollToLower, scrollY, disableScroll, disableLowerScroll, disableUpperScroll
onFetchData使用方式说明
async awit
Page({
async onFetchData(page, limit) {
const res = await getMockData(page, limit);
// 如果有错,请throw error
this.setData({
list: [...this.data.list, ...res.list],
});
return {
total: res.total,
list: res.list,
};
},
})
promise
Page({
onFetchData(page, limit) {s
return getMockData(page, limit).then(res => {
// 如果有错,请throw error
this.setData({
list: [...this.data.list, ...res.list],
});
return {
total: res.total,
list: res.list,
};
})
},
})
一行多列实现方案
修改组件内部的 adc-flat-list-item-container 类,并配置好 item 的样式就可以实现。 使用限制:一行多列暂不支持开启虚拟滚动! 下面是一行两列的示例代码:
<adc-flat-list>
<view class="item"</view>
</adc-flat-list>
.adc-flat-list-item-container {
display: flex;
flex-wrap: wrap;
}
.item {
box-sizing: border-box;
width: 50%;
padding: 24rpx;
}
.item:nth-child(odd) {
padding-right: 12rpx;
}
.item:nth-child(even) {
padding-left: 12rpx;
}
下拉刷新开启说明
下拉刷新与普通刷新不同,在成功获取新数据前,不会销毁原有的数据。
使用限制:下拉刷新使用touchMove实现,因此在使用过程中注意可能和其他滚动事件,touchMove事件带来冲突。 不能再使用小程序原生的下拉刷新功能,需要在页面或app.json中配置"allowsBounceVertical": "NO" 需要在onFetchData中做相关配合,在第三个参数type中会传'pullDown',示例代码如下:
Page({
async onFetchData(page, limit, type) {
const res = await getMockData(page, limit);
// 如果有错,请throw error
if (type === 'pullDown') {
// 下拉刷新
this.setData({
// 下拉刷新时,page为1,因此获取的就是第一页的数据,直接将res.list放入list中更新列表
list: res.list,
});
} else {
// 普通加载模式
this.setData({
list: [...this.data.list, ...res.list],
});
}
return {
total: res.total,
list: res.list,
};
},
})
瀑布流
瀑布流分为两种:
1. 能预知 item 高度的瀑布流(mode=1)
:每一个 item 渲染出来后,能立即获取 item 的尺寸(通过my.createSelectorQuery
)。例如一个 item 中包含的图片事先就知道尺寸,通过设置css,在图片load完成之前就把宽高固定。这种瀑布流的每个 item 能并行加载,每次并行加载一页。
2. 不能预知 item 高度的瀑布流(mode=2)
:例如 item 中包含图片,但不能预知图片的尺寸。此种瀑布流的 item 采用串行加载——一个 item 加载完成,能获取高度后,再去加载下一个。这种瀑布流如果网络条件不好,图片加载慢,体验肯定是要差一些的。
使用限制:瀑布流暂不支持开启虚拟滚动!每个item中必须要有id
Waterfall参数
属性 | 必填 | 参数类型 | 参数说明 | 默认值 | 示例 |
---|---|---|---|---|---|
mode | 否 | 1 | 2 | 1是预知高度瀑布流,2是未知高度瀑布流 | 1 | -- |
column | 否 | Number | 列数 | 2 | -- |
gutter | 否 | String | item 间隔 | '24rpx' | -- |
preRenderRow | 否 | Number | 首页预渲染 item 的行数,未知高度瀑布流专用。因为 item 为串行加载,首页加载数量过少可能不美观。通过preRenderRow可预先并行加载几行的 item,不计算它们的高度 | 2 | -- |
timeout | 否 | Number(ms) | 图片加载超时时间,未知高度瀑布流专用,防止串行加载图片遇到阻塞 | 5000 | -- |
子组件 Waterfall-Image
瀑布流中的使用图片组件(一个item只能有一张)
属性 | 必填 | 参数类型 | 参数说明 | 默认值 | 示例 |
---|---|---|---|---|---|
scope | 是 | slot-scope | 只需将slot-scope的值传入,详见示例 | -- | scope="{{props}}" |
imageSrc | 是 | String | 图片地址 | -- | -- |
loadingSrc | 否 | String | 正式图片加载成功前显示的预览图片。不用图片,只在style中指定一个背景色效果也不错 | -- | -- |
style | 是 | String | 图片的style。其中,height必须指定,backgroundColor可配合预览图片设置合适的颜色。详见示例 | -- | -- |
示例:已知高度瀑布流
{
"usingComponents": {
"adc-flat-list": "/components/es/index",
"waterfall-image": "/components/es/waterfall-image/index"
}
}
.container {
padding: 0 24rpx;
}
<adc-flat-list list="{{list}}"
className="container"
onFetchData="onFetchData"
pullDownRefresh
waterfall>
<view slot-scope="props">
<!-- 这里按比例计算出了图片高度。当图片未加载完成时,显示预览图片 -->
<!-- style里的height, background-color都是必填的 -->
<!-- width默认设定100%,height需要计算得出,background-color选一个和loading图片匹配的颜色 -->
<!-- 高度的计算方法:图片设置高度 = 图片设置宽度 * 图片尺寸高度 / 图片尺寸宽度 -->
<!-- 本例的计算方法:750rpx是总宽,减去24rpx*3的间距,再除以2(有2列)就是图片设置宽度。本例图片尺寸宽度为300,高是props.item.height -->
<waterfall-image scope="{{props}}"
style="height: calc((750rpx - 72rpx) * {{props.item.height}} / 600); background-color: #eeedee;"
imageSrc="{{props.item.imageUrl}}"
loadingSrc="https://tva1.sinaimg.cn/large/006APoFYly1g8mf9qe5udg30jz0jzjtr.gif" />
<view>商品编号:{{props.index}}</view>
<view>商品名称:{{props.item.name}}</view>
<view>商品价格:{{props.item.price}}</view>
</view>
</adc-flat-list>
const list = (function () {
const arr = [];
for (let i = 0; i < 51; i++) {
const height = Math.floor(Math.random() * 600) + 50;
arr.push({
id: i + 1,
price: Math.ceil(Math.random() * 50),
name: ['茄宝娜雪平锅', 'stylor多功能喷雾拖把', '擦手巾'][i % 3],
imageUrl: `https://picsum.photos/300/${height}?random=${Math.random()}`,
height,
});
}
return arr;
})();
function getMockData(page, limit) {
return new Promise((resolve) => {
setTimeout(() => {
const start = (page - 1) * limit;
const end = start + limit;
resolve({
list: list.slice(start, end),
total: list.length,
});
}, 500);
});
}
Page({
data: {
list: [],
},
async onFetchData(page, limit, type) {
const res = await getMockData(page, limit);
if (type === 'pullDown') {
// 下拉刷新
// mock数据改变
list[0].price += 1;
this.setData({
list: res.list,
});
} else {
// 普通加载模式
this.setData({
list: [...this.data.list, ...res.list],
});
}
return res;
},
});
示例:未知高度瀑布流
<adc-flat-list list="{{list}}"
className="container"
onFetchData="onFetchData"
pullDownRefresh
waterfall="{{mode: 2}}">
<view slot-scope="props">
<!-- height也是必填,指定预览图片的高度。预览图片最好不要高过正式图片的高度,否则可能会有抖动 -->
<waterfall-image scope="{{props}}"
style="height:300rpx;background-color: #eeedee;"
imageSrc="{{props.item.imageUrl}}"
loadingSrc="https://tva1.sinaimg.cn/large/006APoFYly1g8mf9qe5udg30jz0jzjtr.gif" />
<view>商品编号:{{props.index}}</view>
<view>商品名称:{{props.item.name}}</view>
<view>商品价格:{{props.item.price}}</view>
</view>
</adc-flat-list>