List 列表
通用列表。
何时使用 #
最基础的列表展示,可承载文字、列表、图片、段落,常用于后台数据展示页面。
代码演示
- [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.
- 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.
- 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.
import { Divider, List, Typography } from 'antd';
import React from 'react';
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.',
const App: React.FC = () => (
<Divider orientation="left">Default Size</Divider>
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>
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>
size="large"
header={<div>Header</div>}
footer={<div>Footer</div>}
bordered
dataSource={data}
renderItem={item => <List.Item>{item}</List.Item>}
export default App;
import { Avatar, List } from 'antd';
import React from 'react';
const data = [
title: 'Ant Design Title 1',
title: 'Ant Design Title 2',
title: 'Ant Design Title 3',
title: 'Ant Design Title 4',
const App: React.FC = () => (
itemLayout="horizontal"
dataSource={data}
renderItem={item => (
<List.Item>
<List.Item.Meta
avatar={<Avatar src="https://joeschmoe.io/api/v1/random" />}
title={<a href="https://ant.design">{item.title}</a>}
description="Ant Design, a design language for background applications, is refined by Ant UED Team"
</List.Item>
export default App;
import { Avatar, Button, List, Skeleton } from 'antd';
import React, { useEffect, useState } from 'react';
interface DataType {
gender?: string;
name: {
title?: string;
first?: string;
last?: string;
email?: string;
picture: {
large?: string;
medium?: string;
thumbnail?: string;
nat?: string;
loading: boolean;
const count = 3;
const fakeDataUrl = `https://randomuser.me/api/?results=${count}&inc=name,gender,email,nat,picture&noinfo`;
const App: React.FC = () => {
const [initLoading, setInitLoading] = useState(true);
const [loading, setLoading] = useState(false);
const [data, setData] = useState<DataType[]>([]);
const [list, setList] = useState<DataType[]>([]);
useEffect(() => {
fetch(fakeDataUrl)
.then(res => res.json())
.then(res => {
setInitLoading(false);
setData(res.results);
setList(res.results);
});
}, []);
const onLoadMore = () => {
setLoading(true);
setList(
data.concat([...new Array(count)].map(() => ({ loading: true, name: {}, picture: {} }))),
fetch(fakeDataUrl)
.then(res => res.json())
.then(res => {
const newData = data.concat(res.results);
setData(
newData);
setList(newData);
setLoading(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'));
});
const loadMore =
!initLoading && !loading ? (
style={{
textAlign: 'center',
marginTop: 12,
height: 32,
lineHeight: '32px',
<Button onClick={onLoadMore}>loading more</Button>
</div>
) : null;
return (
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://ant.design">{item.name?.last}</a>}
description="Ant Design, a design language for background applications, is refined by Ant UED Team"
<div>content</div>
</Skeleton>
</List.Item>
export default App;
.demo-loadmore-list {
min-height: 350px;
}
-
-
156
-
156
-
2
-
-
-
156
-
156
-
2
-
-
-
156
-
156
-
2
-
import { LikeOutlined, MessageOutlined, StarOutlined } from '@ant-design/icons';
import { Avatar, List, Space } from 'antd';
import React from 'react';
const data = Array.from({ length: 23 }).map((_, i) => ({
href: 'https://ant.design',
title: `ant design part ${i}`,
avatar: 'https://joeschmoe.io/api/v1/random',
description:
'Ant Design, a design language for background applications, is refined by Ant 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 }: { icon: React.FC; text: string }) => (
<Space>
{React.createElement(icon)}
{text}
</
Space>
const App: React.FC = () => (
itemLayout="vertical"
size="large"
pagination={{
onChange: page => {
console.log(page);
pageSize: 3,
dataSource={data}
footer={
<b>ant 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={
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>
export default App;
import
{ Card, List } from 'antd';
import React from 'react';
const data = [
title: 'Title 1',
title: 'Title 2',
title: 'Title 3',
title: 'Title 4',
const App: React.FC = () => (
grid={{ gutter: 16, column: 4 }}
dataSource={data}
renderItem={item => (
<List.Item>
<Card title={item.title}>Card content</Card>
</List.Item>
export default App;
import { Card, List } from 'antd';
import React from 'react';
const data = [
title: 'Title 1',
title: 'Title 2',
title: 'Title 3',
title: 'Title 4',
title: 'Title 5',
title: 'Title 6',
const App: React.FC = () => (
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>
export default App;
import { Avatar, Divider, List, Skeleton } from 'antd';
import React, { useEffect, useState } from 'react';
import InfiniteScroll from 'react-infinite-scroll-component';
interface DataType {
gender: string;
name: {
title: string;
first: string;
last: string;
email: string;
picture: {
large: string;
medium: string;
thumbnail: string;
nat: string;
const App: React.FC = () => {
const [loading, setLoading] = useState(false);
const [data, setData] = useState<DataType[]>([]);
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 (
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"
dataSource=
{data}
renderItem={item => (
<List.Item key={item.email}>
<List.Item.Meta
avatar={<Avatar src={item.picture.large} />}
title={<a href="https://ant.design">{item.name.last}</a>}
description={item.email}
<div>Content</div>
</List.Item>
</InfiniteScroll>
</div>
export default App;
import { Avatar, List, message } from 'antd';
import VirtualList from 'rc-virtual-list';
import React, { useEffect, useState } from 'react';
interface UserItem {
email: string;
gender: string;
name: {
first: string;
last: string;
title: string;
nat: string;
picture: {
large: string;
medium: string;
thumbnail: string;
const fakeDataUrl =
'https://randomuser.me/api/?results=20&inc=name,gender,email,nat,picture&noinfo';
const ContainerHeight = 400;
const App: React.FC = () => {
const [data, setData] = useState<UserItem[]>([]);
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: React.UIEvent<HTMLElement, UIEvent>) => {
if (e.currentTarget.scrollHeight - e.currentTarget.scrollTop === ContainerHeight) {
appendData();
return (
<VirtualList
data={data}
height={ContainerHeight}
itemHeight={47}
itemKey="email"
onScroll={onScroll}
{(item: UserItem) => (
<List.Item key={item.email}>
<List.Item.Meta
avatar={<Avatar src={item.picture.large} />}
title={<a href="https://ant.design">{item.name.last}</a>}
description={item.email}
<div>Content</div>
</List.Item>
</VirtualList>
</List>
export default App;
API #
另外我们封装了
ProList
,在
antd
List 之上扩展了更多便捷易用的功能,比如多选,展开等功能,使用体验贴近 Table,欢迎尝试使用。
List #
参数 | 说明 | 类型 | 默认值 | 版本 |
---|---|---|---|---|
bordered | 是否展示边框 | boolean | false | |
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 | object | false | |
renderItem |
当使用 dataSource 时,可以用
renderItem
自定义渲染列表项
|
(item) => ReactNode | - | |
rowKey |
当
renderItem
自定义渲染列表项有效时,自定义每一行的
key
的获取方式
|
keyof
T
|
(item: T) =>
React.Key
|
"key"
|
|
size | list 的尺寸 |
default
|
large
|
small
|
default
|
|
split | 是否展示分割线 | boolean | true |
pagination #
分页的配置项。
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
position | 指定分页显示的位置 |
top
|
bottom
|
both
|
bottom
|
更多配置项,请查看
Pagination
。
List grid props #
参数 | 说明 | 类型 | 默认值 | 版本 |
---|---|---|---|---|
column | 列数 | number | - | |
gutter | 栅格间隔 | number | 0 | |
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 |
额外内容, 通常用在
itemLayout
为
vertical
的情况下, 展示右侧内容;
horizontal
展示在列表元素最右侧
|
ReactNode | - |
List.Item.Meta #
参数 | 说明 | 类型 | 默认值 | 版本 |
---|---|---|---|---|
avatar | 列表元素的图标 | ReactNode | - | |
description | 列表元素的描述内容 | ReactNode | - | |
title | 列表元素的标题 | ReactNode | - |