List列表

通用列表。

何时使用#

最基础的列表展示,可承载文字、列表、图片、段落,常用于后台数据展示页面。

代码演示

Header
  • [ITEM] Racing car sprays burning fuel into crowd.
  • [ITEM] Japanese princess to wed commoner.
  • [ITEM] Australian walks 100km after outback crash.
  • [ITEM] Man charged over missing wedding girl.
  • [ITEM] Los Angeles battles huge wildfires.
Header
  • Racing car sprays burning fuel into crowd.
  • Japanese princess to wed commoner.
  • Australian walks 100km after outback crash.
  • Man charged over missing wedding girl.
  • Los Angeles battles huge wildfires.
Header
  • Racing car sprays burning fuel into crowd.
  • Japanese princess to wed commoner.
  • Australian walks 100km after outback crash.
  • Man charged over missing wedding girl.
  • Los Angeles battles huge wildfires.

列表拥有大、中、小三种尺寸。

通过设置 sizelarge small 分别把按钮设为大、小尺寸。若不设置 size,则尺寸为中。

可通过设置 headerfooter,来自定义列表头部和尾部。

expand codeexpand code
import { List, Typography, Divider } from 'sld';

const data = [
  'Racing car sprays burning fuel into crowd.',
  'Japanese princess to wed commoner.',
  'Australian walks 100km after outback crash.',
  'Man charged over missing wedding girl.',
  'Los Angeles battles huge wildfires.',
];

ReactDOM.render(
  <>
    <Divider orientation="left">Default Size</Divider>
    <List
      header={<div>Header</div>}
      footer={<div>Footer</div>}
      bordered
      dataSource={data}
      renderItem={item => (
        <List.Item>
          <Typography.Text mark>[ITEM]</Typography.Text> {item}
        </List.Item>
      )}
    />
    <Divider orientation="left">Small Size</Divider>
    <List
      size="small"
      header={<div>Header</div>}
      footer={<div>Footer</div>}
      bordered
      dataSource={data}
      renderItem={item => <List.Item>{item}</List.Item>}
    />
    <Divider orientation="left">Large Size</Divider>
    <List
      size="large"
      header={<div>Header</div>}
      footer={<div>Footer</div>}
      bordered
      dataSource={data}
      renderItem={item => <List.Item>{item}</List.Item>}
    />
  </>,
  mountNode,
);
  • SLING Design Title 1

    SLING Design, a design language for background applications, is refined by SLING UED Team
  • SLING Design Title 2

    SLING Design, a design language for background applications, is refined by SLING UED Team
  • SLING Design Title 3

    SLING Design, a design language for background applications, is refined by SLING UED Team
  • SLING Design Title 4

    SLING Design, a design language for background applications, is refined by SLING UED Team

基础列表。

expand codeexpand code
import { List, Avatar } from 'sld';

const data = [
  {
    title: 'SLING Design Title 1',
  },
  {
    title: 'SLING Design Title 2',
  },
  {
    title: 'SLING Design Title 3',
  },
  {
    title: 'SLING Design Title 4',
  },
];

ReactDOM.render(
  <List
    itemLayout="horizontal"
    dataSource={data}
    renderItem={item => (
      <List.Item>
        <List.Item.Meta
          avatar={<Avatar src="https://joeschmoe.io/api/v1/random" />}
          title={<a href="#">{item.title}</a>}
          description="SLING Design, a design language for background applications, is refined by SLING UED Team"
        />
      </List.Item>
    )}
  />,
  mountNode,
);

可通过 loadMore 属性实现加载更多功能。

expand codeexpand code
import { List, Avatar, Button, Skeleton } from 'sld';

const count = 3;
const fakeDataUrl = `https://randomuser.me/api/?results=${count}&inc=name,gender,email,nat,picture&noinfo`;

class LoadMoreList extends React.Component {
  state = {
    initLoading: true,
    loading: false,
    data: [],
    list: [],
  };

  componentDidMount() {
    fetch(fakeDataUrl)
      .then(res => res.json())
      .then(res => {
        this.setState({
          initLoading: false,
          data: res.results,
          list: res.results,
        });
      });
  }

  onLoadMore = () => {
    this.setState({
      loading: true,
      list: this.state.data.concat(
        [...new Array(count)].map(() => ({ loading: true, name: {}, picture: {} })),
      ),
    });
    fetch(fakeDataUrl)
      .then(res => res.json())
      .then(res => {
        const data = this.state.data.concat(res.results);
        this.setState(
          {
            data,
            list: data,
            loading: false,
          },
          () => {
            // Resetting window's offsetTop so as to display react-virtualized demo underfloor.
            // In real scene, you can using public method of react-virtualized:
            // https://stackoverflow.com/questions/46700726/how-to-use-public-method-updateposition-of-react-virtualized
            window.dispatchEvent(new Event('resize'));
          },
        );
      });
  };

  render() {
    const { initLoading, loading, list } = this.state;
    const loadMore =
      !initLoading && !loading ? (
        <div
          style={{
            textAlign: 'center',
            marginTop: 12,
            height: 32,
            lineHeight: '32px',
          }}
        >
          <Button onClick={this.onLoadMore}>loading more</Button>
        </div>
      ) : null;

    return (
      <List
        className="demo-loadmore-list"
        loading={initLoading}
        itemLayout="horizontal"
        loadMore={loadMore}
        dataSource={list}
        renderItem={item => (
          <List.Item
            actions={[<a key="list-loadmore-edit">edit</a>, <a key="list-loadmore-more">more</a>]}
          >
            <Skeleton avatar title={false} loading={item.loading} active>
              <List.Item.Meta
                avatar={<Avatar src={item.picture.large} />}
                title={<a href="https://slingdesign.dtyunxi.com">{item.name.last}</a>}
                description="SLing Design, a design language for background applications, is refined by SLing UED Team"
              />
              <div>content</div>
            </Skeleton>
          </List.Item>
        )}
      />
    );
  }
}

ReactDOM.render(<LoadMoreList />, mountNode);
.demo-loadmore-list {
  min-height: 350px;
}
  • SLING Design part 0

    SLING Design, a design language for background applications, is refined by SLING UED Team.
    We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.
    • 156
    • 156
    • 2
    logo
  • SLING Design part 1

    SLING Design, a design language for background applications, is refined by SLING UED Team.
    We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.
    • 156
    • 156
    • 2
    logo
  • SLING Design part 2

    SLING Design, a design language for background applications, is refined by SLING UED Team.
    We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.
    • 156
    • 156
    • 2
    logo

通过设置 itemLayout 属性为 vertical 可实现竖排列表样式。

expand codeexpand code
import { List, Avatar, Space } from 'sld';
import { MessageOutlined, LikeOutlined, StarOutlined } from '@sld-icon/icons';

const listData = [];
for (let i = 0; i < 23; i++) {
  listData.push({
    href: '#',
    title: `SLING Design part ${i}`,
    avatar: 'https://joeschmoe.io/api/v1/random',
    description:
      'SLING Design, a design language for background applications, is refined by SLING UED Team.',
    content:
      'We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.',
  });
}

const IconText = ({ icon, text }) => (
  <Space>
    {React.createElement(icon)}
    {text}
  </Space>
);

ReactDOM.render(
  <List
    itemLayout="vertical"
    size="large"
    pagination={{
      onChange: page => {
        console.log(page);
      },
      pageSize: 3,
    }}
    dataSource={listData}
    footer={
      <div>
        <b>SLING Design</b> footer part
      </div>
    }
    renderItem={item => (
      <List.Item
        key={item.title}
        actions={[
          <IconText icon={StarOutlined} text="156" key="list-vertical-star-o" />,
          <IconText icon={LikeOutlined} text="156" key="list-vertical-like-o" />,
          <IconText icon={MessageOutlined} text="2" key="list-vertical-message" />,
        ]}
        extra={
          <img
            width={272}
            alt="logo"
            src="https://gw.alipayobjects.com/zos/rmsportal/mqaQswcyDLcXyDKnZfES.png"
          />
        }
      >
        <List.Item.Meta
          avatar={<Avatar src={item.avatar} />}
          title={<a href={item.href}>{item.title}</a>}
          description={item.description}
        />
        {item.content}
      </List.Item>
    )}
  />,
  mountNode,
);
Title 1
Card content
Title 2
Card content
Title 3
Card content
Title 4
Card content

可以通过设置 Listgrid 属性来实现栅格列表,column 可设置期望显示的列数。

expand codeexpand code
import { List, Card } from 'sld';

const data = [
  {
    title: 'Title 1',
  },
  {
    title: 'Title 2',
  },
  {
    title: 'Title 3',
  },
  {
    title: 'Title 4',
  },
];

ReactDOM.render(
  <List
    grid={{ gutter: 16, column: 4 }}
    dataSource={data}
    renderItem={item => (
      <List.Item>
        <Card title={item.title}>Card content</Card>
      </List.Item>
    )}
  />,
  mountNode,
);
Title 1
Card content
Title 2
Card content
Title 3
Card content
Title 4
Card content
Title 5
Card content
Title 6
Card content

响应式的栅格列表。尺寸与 Layout Grid 保持一致。

expand codeexpand code
import { List, Card } from 'sld';

const data = [
  {
    title: 'Title 1',
  },
  {
    title: 'Title 2',
  },
  {
    title: 'Title 3',
  },
  {
    title: 'Title 4',
  },
  {
    title: 'Title 5',
  },
  {
    title: 'Title 6',
  },
];

ReactDOM.render(
  <List
    grid={{
      gutter: 16,
      xs: 1,
      sm: 2,
      md: 4,
      lg: 4,
      xl: 6,
      xxl: 3,
    }}
    dataSource={data}
    renderItem={item => (
      <List.Item>
        <Card title={item.title}>Card content</Card>
      </List.Item>
    )}
  />,
  mountNode,
);
No Data

结合 react-infinite-scroll-component 实现滚动自动加载列表。

expand codeexpand code
import React, { useState, useEffect } from 'react';
import { List, message, Avatar, Skeleton, Divider } from 'sld';
import InfiniteScroll from 'react-infinite-scroll-component';

const InfiniteListExample = () => {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState([]);

  const loadMoreData = () => {
    if (loading) {
      return;
    }
    setLoading(true);
    fetch('https://randomuser.me/api/?results=10&inc=name,gender,email,nat,picture&noinfo')
      .then(res => res.json())
      .then(body => {
        setData([...data, ...body.results]);
        setLoading(false);
      })
      .catch(() => {
        setLoading(false);
      });
  };

  useEffect(() => {
    loadMoreData();
  }, []);

  return (
    <div
      id="scrollableDiv"
      style={{
        height: 400,
        overflow: 'auto',
        padding: '0 16px',
        border: '1px solid rgba(140, 140, 140, 0.35)',
      }}
    >
      <InfiniteScroll
        dataLength={data.length}
        next={loadMoreData}
        hasMore={data.length < 50}
        loader={<Skeleton avatar paragraph={{ rows: 1 }} active />}
        endMessage={<Divider plain>It is all, nothing more 🤐</Divider>}
        scrollableTarget="scrollableDiv"
      >
        <List
          dataSource={data}
          renderItem={item => (
            <List.Item key={item.id}>
              <List.Item.Meta
                avatar={<Avatar src={item.picture.large} />}
                title={<a href="https://slingdesign.dtyunxi.com">{item.name.last}</a>}
                description={item.email}
              />
              <div>Content</div>
            </List.Item>
          )}
        />
      </InfiniteScroll>
    </div>
  );
};

ReactDOM.render(<InfiniteListExample />, mountNode);

结合 rc-virtual-list 实现滚动加载无限长列表,能够提高数据量大时候长列表的性能。

expand codeexpand code
import React, { useState, useEffect } from 'react';
import { List, message, Avatar } from 'sld';
import VirtualList from 'rc-virtual-list';

const fakeDataUrl =
  'https://randomuser.me/api/?results=20&inc=name,gender,email,nat,picture&noinfo';
const ContainerHeight = 400;

const VirtualizedExample = () => {
  const [data, setData] = useState([]);

  const appendData = () => {
    fetch(fakeDataUrl)
      .then(res => res.json())
      .then(body => {
        setData(data.concat(body.results));
        message.success(`${body.results.length} more items loaded!`);
      });
  };

  useEffect(() => {
    appendData();
  }, []);

  const onScroll = e => {
    if (e.target.scrollHeight - e.target.scrollTop === ContainerHeight) {
      appendData();
    }
  };

  return (
    <List>
      <VirtualList
        data={data}
        height={ContainerHeight}
        itemHeight={47}
        itemKey="email"
        onScroll={onScroll}
      >
        {item => (
          <List.Item key={item.email}>
            <List.Item.Meta
              avatar={<Avatar src={item.picture.large} />}
              title={<a href="https://slingdesign.dtyunxi.com">{item.name.last}</a>}
              description={item.email}
            />
            <div>Content</div>
          </List.Item>
        )}
      </VirtualList>
    </List>
  );
};

ReactDOM.render(<VirtualizedExample />, mountNode);

API#

sld-ui List 之上扩展了更多便捷易用的功能,比如多选,展开等功能,使用体验贴近 Table,欢迎尝试使用。

List#

参数说明类型默认值版本
bordered是否展示边框booleanfalse
dataSource列表数据源any[]-
footer列表底部ReactNode-
grid列表栅格配置object-
header列表头部ReactNode-
itemLayout设置 List.Item 布局, 设置成 vertical 则竖直样式显示, 默认横排string-
loading当卡片内容还在加载中时,可以用 loading 展示一个占位boolean | object (更多)false
loadMore加载更多ReactNode-
locale默认文案设置,目前包括空数据文案object{emptyText: 暂无数据}
pagination对应的 pagination 配置, 设置 false 不显示boolean | objectfalse
renderItem当使用 dataSource 时,可以用 renderItem 自定义渲染列表项(item) => ReactNode-
rowKeyrenderItem 自定义渲染列表项有效时,自定义每一行的 key 的获取方式keyof T | (item: T) => React.Key"key"
sizelist 的尺寸default | large | smalldefault
split是否展示分割线booleantrue

pagination#

分页的配置项。

参数说明类型默认值
position指定分页显示的位置top | bottom | bothbottom

更多配置项,请查看 Pagination

List grid props#

参数说明类型默认值版本
column列数number-
gutter栅格间隔number0
xs<576px 展示的列数number-
sm≥576px 展示的列数number-
md≥768px 展示的列数number-
lg≥992px 展示的列数number-
xl≥1200px 展示的列数number-
xxl≥1600px 展示的列数number-

List.Item#

参数说明类型默认值版本
actions列表操作组,根据 itemLayout 的不同, 位置在卡片底部或者最右侧Array<ReactNode>-
extra额外内容, 通常用在 itemLayoutvertical 的情况下, 展示右侧内容; horizontal 展示在列表元素最右侧ReactNode-

List.Item.Meta#

参数说明类型默认值版本
avatar列表元素的图标ReactNode-
description列表元素的描述内容ReactNode-
title列表元素的标题ReactNode-