# @mas.io/adc-flat-list

> @alipay/adc-flat-list 的组件描述

Latest version **2.0.0** (published 2023-02-17) · ISC license · 0 weekly downloads

## Install

```sh
npm install @mas.io/adc-flat-list
pnpm add @mas.io/adc-flat-list
yarn add @mas.io/adc-flat-list
bun add @mas.io/adc-flat-list
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.0.0 |
| Published | 2023-02-17 |
| First published | 2021-03-31 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 2 |
| Unpacked size | 47.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | mas-author |
| Maintainers | bingjian.guo |

## Links

- npm: https://www.npmjs.com/package/@mas.io/adc-flat-list
- Repository: git@code.alipay.com:tiny-template/adc-flat-list
- npm.io page: https://npm.io/package/@mas.io/adc-flat-list

## Dependencies (2)

- [mini-ali-ui](https://npm.io/package/mini-ali-ui.md) ^1.3.4
- [@mas.io/falcon-core](https://npm.io/package/@mas.io/falcon-core.md) ^1.0.5

## Recent versions

- 2.0.0 (latest) — 2023-02-17
- 1.0.9 — 2022-06-14
- 1.0.7 — 2022-02-15
- 1.0.6 — 2021-09-07
- 1.0.5 — 2021-07-22
- 1.0.4 — 2021-06-22
- 1.0.3 — 2021-06-03
- 1.0.2 — 2021-04-12
- 1.0.1 — 2021-04-08
- 1.0.0 — 2021-03-31

## README

# 安装
```bash
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 | 否 | Array[String] | 加载时的底部提示 |  ['马不停蹄加载更多数据中...', '-- 已经到底了，加不了咯 --'] | --
emptyPageFooter | 否 | Array[{text}] | 空数据页面，错误处理按钮文案（等同于Page-result组件的footer） | [{ text: '刷新' }] | --
id | 否 | String | 如果项目中同时存在多个flat-list组件，并且开启虚拟滚动，需要添加唯一id加以区分 | '' | --
pullDownRefresh | 否 | Boolean | 是否开启下拉刷新。开启方法详见下文 | false | --
pullDownText | 否 | Array[String] | 下拉刷新时显示的文本 | ['下拉刷新', '松开刷新', '刷新成功', '刷新失败'] | --
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的重置需要使用方自己管理

# 在小程序中使用
```json
{
  "usingComponents": {
    "adc-flat-list": "@alipay/adc-flat-list/es/index"
  }
}
```

在 page.axml 中引用组件

```html
<!-- 页面使用方式 -->
<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
```javascript
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
```javascript
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 的样式就可以实现。
<b>使用限制：一行多列暂不支持开启虚拟滚动！</b>
下面是一行两列的示例代码：

```html
<adc-flat-list>
  <view class="item"</view>
</adc-flat-list>
```

```css
.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'，示例代码如下：

```javascript
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 加载完成，能获取高度后，再去加载下一个。这种瀑布流如果网络条件不好，图片加载慢，体验肯定是要差一些的。

<b>使用限制：瀑布流暂不支持开启虚拟滚动！每个item中必须要有id</b>

### 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可配合预览图片设置合适的颜色。详见示例 | -- | --


### 示例：已知高度瀑布流

```json
{
  "usingComponents": {
    "adc-flat-list": "/components/es/index",
    "waterfall-image": "/components/es/waterfall-image/index"
  }
}
```

```css

.container {
  padding: 0 24rpx;
}

```

```html

<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>

```

```javascript

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;
  },
});

```

### 示例：未知高度瀑布流

```html

<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>

```

## Badges

[![TNPM version][tnpm-image]][tnpm-url]
[![TNPM downloads][tnpm-downloads-image]][tnpm-url]

[tnpm-image]: https://npm.alibaba-inc.com/badge/v/@alipay/adc-flat-list.svg
[tnpm-url]: https://npm.alibaba-inc.com/package/@alipay/adc-flat-list
[tnpm-downloads-image]: https://npm.alibaba-inc.com/badge/d/@alipay/adc-flat-list.svg

--------------------

---
_Source: https://npm.io/package/@mas.io/adc-flat-list · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
