SwipeMenuList 3.0.0

SwipeMenuList组件,使用List实现,列表项全部为SwipeMenu。

使用说明

引用方式

import { SwipeMenuList } from '$yo-component';

// 如果你的项目中未使用最新的 ykit-config-yo 插件,可能无法使用上面这个语法糖
// 你仍然可以通过下面这种方式来引用
import SwipeMenuList from 'yo3/component/swipemenulist';

基础使用

SwipeMenuList是一个定制化的 ListList 的不同之处在于它的每一个列表项都是 SwipeMenu。因此除了列表的 dataSource 之外 你还需要指定菜单项的配置,这可以通过 getMenuConfig 属性实现:

<SwipeMenuList
  getMenuConfig = {(item, i) => ({
    action:[
      {
        text:`delete ${i}`
        onTap(item, i, swipeMenu){
          console.log(item, i);
        }
      },
      // ...
    ],
    // ...
  })}
  // ...
/>

它可以接收参数 itemi,分别对应列表项的数据和在数据源中的 index,返回一个符合 SwipeMenu 组件配置规则的对象。通过 这种方式,你可以给列表项定义不同的 SwipeMenu 配置。

getMenuConfig 返回的对象中,action属性用来配置 SwipeMenu 按钮的表现和行为,下面是一个具体的例子:

[
{
    text: '点我',
    onTap(item, i, swipeMenu){
      ToolTip.show(item.text, 1000);
      swipeMenu.close();
    }
  },
  {
    text: '删除',
    onTap(item, i, swipeMenu){
      self.deleteItem(item);
    }
  }
]

需要注意的是,每个按钮的 onTap 回调可以接收到三个参数,这与 SwipeMenu 不同。前两个参数 itemi 是列表项的数据对象和 index,第三个参数是当前列表项对应的 SwipeMenu 的组件实例的引用。实例里通过这个实例的引用调用了 SwipeMenuclose 方法,这样就可以在点击按钮以后关闭这个列表项。

另外,现在通过配置 renderItem 属性指定的渲染区域只有 SwipeMenu 的内容区域。它使用的方式与其他列表组件的 renderItem 完全一致。

SwipeMenuList 继承了 List 的所有特性,无穷模式(指定高度和不指定高度),加载更多和下拉刷新都可以使用。可以参考 List 的文档。

监听菜单项的打开/关闭

SwipeMenuList 提供了两个事件回调函数 onMenuOpenonMenuClose 来监听菜单项打开状态的变化,这在某些场景下会有用(可以观察一下 iOS 的信息功能,在短信上左划整个页面会发生什么变化)。参考下面的代码:

<SwipeMenuList
  dataSource={this.state.dataSource}
  infinite={true}
  infiniteSize={30}
  onMenuOpen={(item, index) => {
    // 参数可以取到当前打开的菜单项的数据和index
    console.log('open', item, index);
  }}
  onMenuClose={(item,index) => {
    // 同上
    console.log('close', item, index);
  }}
/>

一个完整的例子

下面的代码就是右侧 Demo 的源码,这个 Demo 实现了常见的删除列表项的功能:

class SwipeMenuListDemo extends Component {

  static guid = -1;

  append(origDs = this.state.dataSource) {
    this.setState({
      dataSource: origDs.concat(this.renderDataSource(getRandomDataSource(20)))
    });
  }

  refresh() {
    this.setState({ dataSource: this.renderDataSource(getRandomDataSource(20)) })
  }

  deleteItem(item) {
    const newDataSource = this.state.dataSource.filter((it, index) => it.key !== item.key);

    if (newDataSource.length < this.page * 20) {
      this.append(newDataSource);
    }
    else {
      this.setState({
        dataSource: newDataSource
      });
    }
  }

  renderDataSource(ds) {
    const self = this;
    return ds.map((item, i) => ({
      ...item,
      color: 'black',
      key: ++SwipeMenuListDemo.guid
    }));
  }

  constructor() {
    super();
    const self = this;
    const testData = this.renderDataSource(getRandomDataSource(20));
    this.page = 1;
    this.state = {
      dataSource: testData
    };
  }

  toggleColor(item) {
    this.setState({
      dataSource: this.state.dataSource.map(it =>
        it === item ?
          Object.assign({}, it, {
            key: String(it.key).replace(/_\w+/, '') + '_red',
            color: it.color === 'black' ? 'red' : 'black'
          }) : it
      )
    });
  }

  render() {
    const self = this;
    return (
      <Page title="SwipeMenuList Demo" onLeftPress={() => location.href = './index.html'}>
        <SwipeMenuList
          ref="swipemenulist"
          extraClass="yo-scroller-fullscreen"
          getMenuConfig={(item) => ({
            action: [{
              text: item.color === 'black' ? '变红' : '变黑',
              onTap(item, i, swipeMenu) {
                  self.toggleColor(item);
                  swipeMenu.close();
              }
            }, {
                text: '删除',
                onTap(item, i, swipeMenu) {
                  self.deleteItem(item);
                  swipeMenu.close(true);
                }
            }]
          })}
          dataSource={this.state.dataSource}
          infinite={true}
          infiniteSize={15}
          itemHeight={83}
          renderItem={(item, i) => (
            <div style={{ color: item.color, height: 60, width: '100%' }}>
              {'第' + i + '个item:' + item.text}
            </div>
          )}
          usePullRefresh={true}
          onRefresh={() => {
            setTimeout(() => {
              this.refresh();
              this.refs.swipemenulist.stopRefreshing(true);
            }, 500);
          }}
          onItemTap={(item) => {
            Toast.show(item.text);
          }}
          itemTouchClass="item-touch"
          useLoadMore={true}
          onLoad={() => {
            setTimeout(() => {
              this.append();
              ++this.page;
              this.refs.swipemenulist.stopLoading(true);
            }, 500);
          }}
        />
      </Page>
    );
  }
}
属性

dataSource { Array/Immutable List } #

组件数据源,数组类型,与List同名属性完全一致。

默认值: null

uniqueKeyName { String } 3.1.3 #

dataSource 数组项的唯一标识的键值,默认为 key。

例子:renderItem={(item)=><p>{item.someAttr}</p>}

默认值: 'key'

getMenuConfig { Function } 3.0.3 #

这个函数应该返回一个列表项菜单对应的SwipeMenu组件配置对象, 可配置的属性请参考SwipeMenu组件。

默认值: null

方法参数:

参数名 类型 描述 支持版本
item Object 列表项对应的数据对象
index Number 列表项在数据源中的index

renderItem { Function } #

渲染列表项的函数,接受参数item(该项对应的数据源中的配置对象),index(配置对象在数据源中的index),返回JSX或者string 作为SwipeMenu的内容

默认值: null

方法参数:

参数名 类型 描述 支持版本
item Object 列表项对应的数据对象
index Number 列表项在数据源中的index

staticSection { Element } 3.0.3 #

在所有列表项之上渲染的一块静态区域,在开启Infinite模式时,这块区域不会参与列表项的回收复用。

默认值: null

infinite { Bool } #

是否开启无穷列表模式,参考List同名属性

默认值: false

infiniteSize { Bool } #

无穷列表模式中,设置保留在容器中的列表项数量,参考List同名属性

默认值: 20

itemHeight { Number } #

列表项高度,参考List同名属性

默认值: null

itemExtraClass { Function } #

列表项class,可以传入函数/字符串,参考List同名属性

默认值: "item swipemenu-list-item"

方法参数:

参数名 类型 描述 支持版本
item Object 列表项对应的数据对象
index Number 列表项在数据源中的偏移

onItemTap { Function } #

item点击事件回调,参考List同名属性。

注意:点击swipemenu的按钮区域以及菜单展开时不会触发这个事件。

默认值: null

方法参数:

参数名 类型 描述 支持版本
item Object 列表项对应的数据对象
index Number 列表项在数据源中的偏移
dataSource Array 数据源

itemTouchClass { String/Function } 3.0.2 #

列表项被点击时的className,可以接收字符串或者函数,使用方式与itemExtraClass一致。

默认值: item-touch

方法参数:

参数名 类型 描述 支持版本
item Object 列表项对应的数据对象
index Number 列表项在数据源中的index

extraClass { String } #

给List容器dom添加的额外class

默认值: null

style { Object } 3.0.2 #

给组件容器节点绑定的额外样式

默认值: null

usePullRefresh { Bool } #

是否开启下拉刷新

默认值: false

pullRefreshHeight { Number } #

触发下拉刷新状态的高度(一般即为下拉刷新提示区域的高度)

默认值: 40

renderPullRefresh { Function } #

自定义的下拉刷新渲染函数

返回值: Element 用来渲染

onRefresh { Function } #

下拉刷新完成回调

默认值: null

方法参数:

参数名 类型 描述 支持版本
dataSource Array 列表数据源

useLoadMore { Bool } #

是否开启加载更多

默认值: false

loadMoreHeight { Number } #

触发加载更多状态的高度(一般即为加载更多提示区域的高度)

默认值: 40

renderLoadMore { Function } #

自定义的加载更多渲染函数

返回值: Element 用来渲染

onLoad { Function } #

加载更多回调

默认值: null

方法参数:

参数名 类型 描述 支持版本
dataSource Array 列表数据源

offsetY { Number } #

列表初始Y轴偏移

默认值: 0

contentInset { Number } 3.0.13 #

内容区域周围的留白,目前仅支持 bottom。主要用于适配 iPhoneX,在下方留出一定间隙。有『加载更多』时,显示在『加载更多』的下方。可以通过设置背景色来改变留白的颜色。

默认值: {bottom:0}

onScroll { Function } #

列表滚动时触发的回调

默认值: null

方法参数:

参数名 类型 描述 支持版本
offsetY Number y坐标

onScrollEnd { Function } 3.1.4 #

滚动结束之后的回调

默认值: null

方法参数:

参数名 类型 描述 支持版本
offsetY Number 当前 Scroller 的 y 轴偏移量

shouldItemUpdate { Function } #

绑定给列表项组件的shouldComponentUpdate,可以避免额外的render,用于提升列表的滚动性能。 详情请参考List组件同名属性。

默认值: null

方法参数:

参数名 类型 描述 支持版本
next Object 即将传给列表项组件的item对象
now Object 当前列表项组件对应的item对象

deceleration { Number } 3.0.6 #

滚动视图开始惯性滚动时减速的加速度,默认为0.010。

onMenuOpen { Function } 3.0.2 #

在某个菜单项打开的时候触发的回调函数。

默认值: ()=>{}

方法参数:

参数名 类型 描述 支持版本
item Object 打开的菜单项对应的数据对象
index Number 打开的菜单项在dataSource中的index

onMenuClose { Function } 3.0.2 #

在某个菜单项关闭时触发的回调函数。

默认值: ()=>{}

方法参数:

参数名 类型 描述 支持版本
item Object 打开的菜单项对应的数据对象
index Number 打开的菜单项在dataSource中的index

scrollWithoutTouchStart { Bool } 3.0.2 #

实验中的属性 在默认情况下一次用户触发(非调用scrollTo方法)scroller的滚动需要由touchstart事件来启动,在某些情况下,例如scroller从disable状态切换到enable状态时, 可能不能接收到这一瞬间的touchstart事件,这可能导致用户期待的滚动过程没有发生。 开启这个属性为true以后将允许scroller用touchmove启动滚动过程,这可以解决上述场景的问题。

默认值: false

stickyOffset { Number } 3.0.6 #

给staticSection内部吸顶容器设置的y轴偏移。

默认值: 0

方法

refresh 3.0.6 #

在GroupList容器尺寸发生变化时调用,刷新内部的Scroller组件。

resetLoadStatus 3.0.7 #

重置加载更多功能。

方法参数:

参数名 类型 描述 必选 支持版本
hasLoadMore Bool 是否能够加载更多,如果传入false,加载更多区域的文字将会变成 没有更多了,并且继续向下滚动时不会触发onLoadMore。

scrollTo #

滚动到某个位置

方法参数:

参数名 类型 描述 必选 支持版本
y Number y坐标
time Number 动画持续时间

stopRefreshing #

调用 Scroller 同名方法,中止下拉刷新过程。在列表发生下拉刷新之后你应该调用这个方法去中止它(比如服务器响应已经返回的时候),否则刷新不会自动终止。

方法参数:

参数名 类型 描述 必选 支持版本
success Bool 下拉刷新是否成功,默认为 false。
config Object 停止刷新的动画配置。
config.duration number 回到顶部的动画时间,默认是 300ms。
callback Function 回到顶部的动画执行完毕的回调。

startRefreshing #

模拟下拉刷新

stopAnimate #

让列表立刻停止滚动。

stopLoading #

停止加载更多

方法参数:

参数名 类型 描述 必选 支持版本
success Bool 加载成功/加载失败