List列表

通用列表。

何时使用

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

代码演示

List列表 - 图1

简单列表

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

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

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

  1. import { List, Typography, Divider } from 'antd';
  2. const data = [
  3. 'Racing car sprays burning fuel into crowd.',
  4. 'Japanese princess to wed commoner.',
  5. 'Australian walks 100km after outback crash.',
  6. 'Man charged over missing wedding girl.',
  7. 'Los Angeles battles huge wildfires.',
  8. ];
  9. ReactDOM.render(
  10. <>
  11. <Divider orientation="left">Default Size</Divider>
  12. <List
  13. header={<div>Header</div>}
  14. footer={<div>Footer</div>}
  15. bordered
  16. dataSource={data}
  17. renderItem={item => (
  18. <List.Item>
  19. <Typography.Text mark>[ITEM]</Typography.Text> {item}
  20. </List.Item>
  21. )}
  22. />
  23. <Divider orientation="left">Small Size</Divider>
  24. <List
  25. size="small"
  26. header={<div>Header</div>}
  27. footer={<div>Footer</div>}
  28. bordered
  29. dataSource={data}
  30. renderItem={item => <List.Item>{item}</List.Item>}
  31. />
  32. <Divider orientation="left">Large Size</Divider>
  33. <List
  34. size="large"
  35. header={<div>Header</div>}
  36. footer={<div>Footer</div>}
  37. bordered
  38. dataSource={data}
  39. renderItem={item => <List.Item>{item}</List.Item>}
  40. />
  41. </>,
  42. mountNode,
  43. );

List列表 - 图2

基础列表

基础列表。

  1. import { List, Avatar } from 'antd';
  2. const data = [
  3. {
  4. title: 'Ant Design Title 1',
  5. },
  6. {
  7. title: 'Ant Design Title 2',
  8. },
  9. {
  10. title: 'Ant Design Title 3',
  11. },
  12. {
  13. title: 'Ant Design Title 4',
  14. },
  15. ];
  16. ReactDOM.render(
  17. <List
  18. itemLayout="horizontal"
  19. dataSource={data}
  20. renderItem={item => (
  21. <List.Item>
  22. <List.Item.Meta
  23. avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
  24. title={<a href="https://ant.design">{item.title}</a>}
  25. description="Ant Design, a design language for background applications, is refined by Ant UED Team"
  26. />
  27. </List.Item>
  28. )}
  29. />,
  30. mountNode,
  31. );

List列表 - 图3

加载更多

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

  1. import { List, Avatar, Button, Skeleton } from 'antd';
  2. import reqwest from 'reqwest';
  3. const count = 3;
  4. const fakeDataUrl = `https://randomuser.me/api/?results=${count}&inc=name,gender,email,nat&noinfo`;
  5. class LoadMoreList extends React.Component {
  6. state = {
  7. initLoading: true,
  8. loading: false,
  9. data: [],
  10. list: [],
  11. };
  12. componentDidMount() {
  13. this.getData(res => {
  14. this.setState({
  15. initLoading: false,
  16. data: res.results,
  17. list: res.results,
  18. });
  19. });
  20. }
  21. getData = callback => {
  22. reqwest({
  23. url: fakeDataUrl,
  24. type: 'json',
  25. method: 'get',
  26. contentType: 'application/json',
  27. success: res => {
  28. callback(res);
  29. },
  30. });
  31. };
  32. onLoadMore = () => {
  33. this.setState({
  34. loading: true,
  35. list: this.state.data.concat([...new Array(count)].map(() => ({ loading: true, name: {} }))),
  36. });
  37. this.getData(res => {
  38. const data = this.state.data.concat(res.results);
  39. this.setState(
  40. {
  41. data,
  42. list: data,
  43. loading: false,
  44. },
  45. () => {
  46. // Resetting window's offsetTop so as to display react-virtualized demo underfloor.
  47. // In real scene, you can using public method of react-virtualized:
  48. // https://stackoverflow.com/questions/46700726/how-to-use-public-method-updateposition-of-react-virtualized
  49. window.dispatchEvent(new Event('resize'));
  50. },
  51. );
  52. });
  53. };
  54. render() {
  55. const { initLoading, loading, list } = this.state;
  56. const loadMore =
  57. !initLoading && !loading ? (
  58. <div
  59. style={{
  60. textAlign: 'center',
  61. marginTop: 12,
  62. height: 32,
  63. lineHeight: '32px',
  64. }}
  65. >
  66. <Button onClick={this.onLoadMore}>loading more</Button>
  67. </div>
  68. ) : null;
  69. return (
  70. <List
  71. className="demo-loadmore-list"
  72. loading={initLoading}
  73. itemLayout="horizontal"
  74. loadMore={loadMore}
  75. dataSource={list}
  76. renderItem={item => (
  77. <List.Item
  78. actions={[<a key="list-loadmore-edit">edit</a>, <a key="list-loadmore-more">more</a>]}
  79. >
  80. <Skeleton avatar title={false} loading={item.loading} active>
  81. <List.Item.Meta
  82. avatar={
  83. <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
  84. }
  85. title={<a href="https://ant.design">{item.name.last}</a>}
  86. description="Ant Design, a design language for background applications, is refined by Ant UED Team"
  87. />
  88. <div>content</div>
  89. </Skeleton>
  90. </List.Item>
  91. )}
  92. />
  93. );
  94. }
  95. }
  96. ReactDOM.render(<LoadMoreList />, mountNode);
  1. .demo-loadmore-list {
  2. min-height: 350px;
  3. }

List列表 - 图4

竖排列表样式

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

  1. import { List, Avatar, Space } from 'antd';
  2. import { MessageOutlined, LikeOutlined, StarOutlined } from '@ant-design/icons';
  3. const listData = [];
  4. for (let i = 0; i < 23; i++) {
  5. listData.push({
  6. href: 'https://ant.design',
  7. title: `ant design part ${i}`,
  8. avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
  9. description:
  10. 'Ant Design, a design language for background applications, is refined by Ant UED Team.',
  11. content:
  12. '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.',
  13. });
  14. }
  15. const IconText = ({ icon, text }) => (
  16. <Space>
  17. {React.createElement(icon)}
  18. {text}
  19. </Space>
  20. );
  21. ReactDOM.render(
  22. <List
  23. itemLayout="vertical"
  24. size="large"
  25. pagination={{
  26. onChange: page => {
  27. console.log(page);
  28. },
  29. pageSize: 3,
  30. }}
  31. dataSource={listData}
  32. footer={
  33. <div>
  34. <b>ant design</b> footer part
  35. </div>
  36. }
  37. renderItem={item => (
  38. <List.Item
  39. key={item.title}
  40. actions={[
  41. <IconText icon={StarOutlined} text="156" key="list-vertical-star-o" />,
  42. <IconText icon={LikeOutlined} text="156" key="list-vertical-like-o" />,
  43. <IconText icon={MessageOutlined} text="2" key="list-vertical-message" />,
  44. ]}
  45. extra={
  46. <img
  47. width={272}
  48. alt="logo"
  49. src="https://gw.alipayobjects.com/zos/rmsportal/mqaQswcyDLcXyDKnZfES.png"
  50. />
  51. }
  52. >
  53. <List.Item.Meta
  54. avatar={<Avatar src={item.avatar} />}
  55. title={<a href={item.href}>{item.title}</a>}
  56. description={item.description}
  57. />
  58. {item.content}
  59. </List.Item>
  60. )}
  61. />,
  62. mountNode,
  63. );

List列表 - 图5

栅格列表

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

  1. import { List, Card } from 'antd';
  2. const data = [
  3. {
  4. title: 'Title 1',
  5. },
  6. {
  7. title: 'Title 2',
  8. },
  9. {
  10. title: 'Title 3',
  11. },
  12. {
  13. title: 'Title 4',
  14. },
  15. ];
  16. ReactDOM.render(
  17. <List
  18. grid={{ gutter: 16, column: 4 }}
  19. dataSource={data}
  20. renderItem={item => (
  21. <List.Item>
  22. <Card title={item.title}>Card content</Card>
  23. </List.Item>
  24. )}
  25. />,
  26. mountNode,
  27. );

List列表 - 图6

响应式的栅格列表

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

  1. import { List, Card } from 'antd';
  2. const data = [
  3. {
  4. title: 'Title 1',
  5. },
  6. {
  7. title: 'Title 2',
  8. },
  9. {
  10. title: 'Title 3',
  11. },
  12. {
  13. title: 'Title 4',
  14. },
  15. {
  16. title: 'Title 5',
  17. },
  18. {
  19. title: 'Title 6',
  20. },
  21. ];
  22. ReactDOM.render(
  23. <List
  24. grid={{
  25. gutter: 16,
  26. xs: 1,
  27. sm: 2,
  28. md: 4,
  29. lg: 4,
  30. xl: 6,
  31. xxl: 3,
  32. }}
  33. dataSource={data}
  34. renderItem={item => (
  35. <List.Item>
  36. <Card title={item.title}>Card content</Card>
  37. </List.Item>
  38. )}
  39. />,
  40. mountNode,
  41. );

List列表 - 图7

滚动加载

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

  1. import { List, message, Avatar, Spin } from 'antd';
  2. import reqwest from 'reqwest';
  3. import InfiniteScroll from 'react-infinite-scroller';
  4. const fakeDataUrl = 'https://randomuser.me/api/?results=5&inc=name,gender,email,nat&noinfo';
  5. class InfiniteListExample extends React.Component {
  6. state = {
  7. data: [],
  8. loading: false,
  9. hasMore: true,
  10. };
  11. componentDidMount() {
  12. this.fetchData(res => {
  13. this.setState({
  14. data: res.results,
  15. });
  16. });
  17. }
  18. fetchData = callback => {
  19. reqwest({
  20. url: fakeDataUrl,
  21. type: 'json',
  22. method: 'get',
  23. contentType: 'application/json',
  24. success: res => {
  25. callback(res);
  26. },
  27. });
  28. };
  29. handleInfiniteOnLoad = () => {
  30. let { data } = this.state;
  31. this.setState({
  32. loading: true,
  33. });
  34. if (data.length > 14) {
  35. message.warning('Infinite List loaded all');
  36. this.setState({
  37. hasMore: false,
  38. loading: false,
  39. });
  40. return;
  41. }
  42. this.fetchData(res => {
  43. data = data.concat(res.results);
  44. this.setState({
  45. data,
  46. loading: false,
  47. });
  48. });
  49. };
  50. render() {
  51. return (
  52. <div className="demo-infinite-container">
  53. <InfiniteScroll
  54. initialLoad={false}
  55. pageStart={0}
  56. loadMore={this.handleInfiniteOnLoad}
  57. hasMore={!this.state.loading && this.state.hasMore}
  58. useWindow={false}
  59. >
  60. <List
  61. dataSource={this.state.data}
  62. renderItem={item => (
  63. <List.Item key={item.id}>
  64. <List.Item.Meta
  65. avatar={
  66. <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
  67. }
  68. title={<a href="https://ant.design">{item.name.last}</a>}
  69. description={item.email}
  70. />
  71. <div>Content</div>
  72. </List.Item>
  73. )}
  74. >
  75. {this.state.loading && this.state.hasMore && (
  76. <div className="demo-loading-container">
  77. <Spin />
  78. </div>
  79. )}
  80. </List>
  81. </InfiniteScroll>
  82. </div>
  83. );
  84. }
  85. }
  86. ReactDOM.render(<InfiniteListExample />, mountNode);
  1. .demo-infinite-container {
  2. height: 300px;
  3. padding: 8px 24px;
  4. overflow: auto;
  5. border: 1px solid #e8e8e8;
  6. border-radius: 4px;
  7. }
  8. .demo-loading-container {
  9. position: absolute;
  10. bottom: 40px;
  11. width: 100%;
  12. text-align: center;
  13. }

List列表 - 图8

滚动加载无限长列表

结合 react-virtualized 实现滚动加载无限长列表,带有虚拟化(virtualization)功能,能够提高数据量大时候长列表的性能。

virtualized 是在大数据列表中应用的一种技术,主要是为了减少不可见区域不必要的渲染从而提高性能,特别是数据量在成千上万条效果尤为明显。了解更多

  1. import { List, message, Avatar, Spin } from 'antd';
  2. import reqwest from 'reqwest';
  3. import WindowScroller from 'react-virtualized/dist/commonjs/WindowScroller';
  4. import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer';
  5. import VList from 'react-virtualized/dist/commonjs/List';
  6. import InfiniteLoader from 'react-virtualized/dist/commonjs/InfiniteLoader';
  7. const fakeDataUrl = 'https://randomuser.me/api/?results=5&inc=name,gender,email,nat&noinfo';
  8. class VirtualizedExample extends React.Component {
  9. state = {
  10. data: [],
  11. loading: false,
  12. };
  13. loadedRowsMap = {};
  14. componentDidMount() {
  15. this.fetchData(res => {
  16. this.setState({
  17. data: res.results,
  18. });
  19. });
  20. }
  21. fetchData = callback => {
  22. reqwest({
  23. url: fakeDataUrl,
  24. type: 'json',
  25. method: 'get',
  26. contentType: 'application/json',
  27. success: res => {
  28. callback(res);
  29. },
  30. });
  31. };
  32. handleInfiniteOnLoad = ({ startIndex, stopIndex }) => {
  33. let { data } = this.state;
  34. this.setState({
  35. loading: true,
  36. });
  37. for (let i = startIndex; i <= stopIndex; i++) {
  38. // 1 means loading
  39. this.loadedRowsMap[i] = 1;
  40. }
  41. if (data.length > 19) {
  42. message.warning('Virtualized List loaded all');
  43. this.setState({
  44. loading: false,
  45. });
  46. return;
  47. }
  48. this.fetchData(res => {
  49. data = data.concat(res.results);
  50. this.setState({
  51. data,
  52. loading: false,
  53. });
  54. });
  55. };
  56. isRowLoaded = ({ index }) => !!this.loadedRowsMap[index];
  57. renderItem = ({ index, key, style }) => {
  58. const { data } = this.state;
  59. const item = data[index];
  60. return (
  61. <List.Item key={key} style={style}>
  62. <List.Item.Meta
  63. avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
  64. title={<a href="https://ant.design">{item.name.last}</a>}
  65. description={item.email}
  66. />
  67. <div>Content</div>
  68. </List.Item>
  69. );
  70. };
  71. render() {
  72. const { data } = this.state;
  73. const vlist = ({ height, isScrolling, onChildScroll, scrollTop, onRowsRendered, width }) => (
  74. <VList
  75. autoHeight
  76. height={height}
  77. isScrolling={isScrolling}
  78. onScroll={onChildScroll}
  79. overscanRowCount={2}
  80. rowCount={data.length}
  81. rowHeight={73}
  82. rowRenderer={this.renderItem}
  83. onRowsRendered={onRowsRendered}
  84. scrollTop={scrollTop}
  85. width={width}
  86. />
  87. );
  88. const autoSize = ({ height, isScrolling, onChildScroll, scrollTop, onRowsRendered }) => (
  89. <AutoSizer disableHeight>
  90. {({ width }) =>
  91. vlist({
  92. height,
  93. isScrolling,
  94. onChildScroll,
  95. scrollTop,
  96. onRowsRendered,
  97. width,
  98. })
  99. }
  100. </AutoSizer>
  101. );
  102. const infiniteLoader = ({ height, isScrolling, onChildScroll, scrollTop }) => (
  103. <InfiniteLoader
  104. isRowLoaded={this.isRowLoaded}
  105. loadMoreRows={this.handleInfiniteOnLoad}
  106. rowCount={data.length}
  107. >
  108. {({ onRowsRendered }) =>
  109. autoSize({
  110. height,
  111. isScrolling,
  112. onChildScroll,
  113. scrollTop,
  114. onRowsRendered,
  115. })
  116. }
  117. </InfiniteLoader>
  118. );
  119. return (
  120. <List>
  121. {data.length > 0 && <WindowScroller>{infiniteLoader}</WindowScroller>}
  122. {this.state.loading && <Spin className="demo-loading" />}
  123. </List>
  124. );
  125. }
  126. }
  127. ReactDOM.render(<VirtualizedExample />, mountNode);
  1. .demo-loading {
  2. position: absolute;
  3. bottom: -40px;
  4. left: 50%;
  5. }

API

另外我们封装了 ProList,在 antd 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 的获取方式((item: T) => string)list-item-${index}
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-