List列表
通用列表。
何时使用#
最基础的列表展示,可承载文字、列表、图片、段落,常用于后台数据展示页面。
代码演示
Default Size
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.
Small Size
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.
Large Size
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.
import { List } from 'hzero-ui';
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(
<div>
<h3 style={{ marginBottom: 16 }}>Default Size</h3>
<List
header={<div>Header</div>}
footer={<div>Footer</div>}
bordered
dataSource={data}
renderItem={item => (<List.Item>{item}</List.Item>)}
/>
<h3 style={{ margin: '16px 0' }}>Small Size</h3>
<List
size="small"
header={<div>Header</div>}
footer={<div>Footer</div>}
bordered
dataSource={data}
renderItem={item => (<List.Item>{item}</List.Item>)}
/>
<h3 style={{ margin: '16px 0' }}>Large Size</h3>
<List
size="large"
header={<div>Header</div>}
footer={<div>Footer</div>}
bordered
dataSource={data}
renderItem={item => (<List.Item>{item}</List.Item>)}
/>
</div>,
mountNode);
import { List, Avatar } from 'hzero-ui';
const data = [
{
title: 'Ant Design Title 1',
},
{
title: 'Ant Design Title 2',
},
{
title: 'Ant Design Title 3',
},
{
title: 'Ant Design Title 4',
},
];
ReactDOM.render(
<List
itemLayout="horizontal"
dataSource={data}
renderItem={item => (
<List.Item>
<List.Item.Meta
avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
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>
)}
/>,
mountNode);
import { List, Avatar, Button, Spin } from 'hzero-ui';
import reqwest from 'reqwest';
const fakeDataUrl = 'https://randomuser.me/api/?results=5&inc=name,gender,email,nat&noinfo';
class LoadMoreList extends React.Component {
state = {
loading: true,
loadingMore: false,
showLoadingMore: true,
data: [],
}
componentDidMount() {
this.getData((res) => {
this.setState({
loading: false,
data: res.results,
});
});
}
getData = (callback) => {
reqwest({
url: fakeDataUrl,
type: 'json',
method: 'get',
contentType: 'application/json',
success: (res) => {
callback(res);
},
});
}
onLoadMore = () => {
this.setState({
loadingMore: true,
});
this.getData((res) => {
const data = this.state.data.concat(res.results);
this.setState({
data,
loadingMore: 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 { loading, loadingMore, showLoadingMore, data } = this.state;
const loadMore = showLoadingMore ? (
<div style={{ textAlign: 'center', marginTop: 12, height: 32, lineHeight: '32px' }}>
{loadingMore && <Spin />}
{!loadingMore && <Button onClick={this.onLoadMore}>loading more</Button>}
</div>
) : null;
return (
<List
className="demo-loadmore-list"
loading={loading}
itemLayout="horizontal"
loadMore={loadMore}
dataSource={data}
renderItem={item => (
<List.Item actions={[<a>edit</a>, <a>more</a>]}>
<List.Item.Meta
avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
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>
</List.Item>
)}
/>
);
}
}
ReactDOM.render(<LoadMoreList />, mountNode);
.demo-loadmore-list {
min-height: 350px;
}
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

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

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

import { List, Avatar, Icon } from 'hzero-ui';
const listData = [];
for (let i = 0; i < 23; i++) {
listData.push({
href: 'http://ant.design',
title: `ant design part ${i}`,
avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
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 = ({ type, text }) => (
<span>
<Icon type={type} style={{ marginRight: 8 }} />
{text}
</span>
);
ReactDOM.render(
<List
itemLayout="vertical"
size="large"
pagination={{
onChange: (page) => {
console.log(page);
},
pageSize: 3,
}}
dataSource={listData}
footer={<div><b>ant design</b> footer part</div>}
renderItem={item => (
<List.Item
key={item.title}
actions={[<IconText type="star-o" text="156" />, <IconText type="like-o" text="156" />, <IconText type="message" text="2" />]}
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
import { List, Card } from 'hzero-ui';
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
import { List, Card } from 'hzero-ui';
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);
暂无数据
import { List, message, Avatar, Spin } from 'hzero-ui';
import reqwest from 'reqwest';
import InfiniteScroll from 'react-infinite-scroller';
const fakeDataUrl = 'https://randomuser.me/api/?results=5&inc=name,gender,email,nat&noinfo';
class InfiniteListExample extends React.Component {
state = {
data: [],
loading: false,
hasMore: true,
}
getData = (callback) => {
reqwest({
url: fakeDataUrl,
type: 'json',
method: 'get',
contentType: 'application/json',
success: (res) => {
callback(res);
},
});
}
componentDidMount() {
this.getData((res) => {
this.setState({
data: res.results,
});
});
}
handleInfiniteOnLoad = () => {
let data = this.state.data;
this.setState({
loading: true,
});
if (data.length > 14) {
message.warning('Infinite List loaded all');
this.setState({
hasMore: false,
loading: false,
});
return;
}
this.getData((res) => {
data = data.concat(res.results);
this.setState({
data,
loading: false,
});
});
}
render() {
return (
<div className="demo-infinite-container">
<InfiniteScroll
initialLoad={false}
pageStart={0}
loadMore={this.handleInfiniteOnLoad}
hasMore={!this.state.loading && this.state.hasMore}
useWindow={false}
>
<List
dataSource={this.state.data}
renderItem={item => (
<List.Item key={item.id}>
<List.Item.Meta
avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
title={<a href="https://ant.design">{item.name.last}</a>}
description={item.email}
/>
<div>Content</div>
</List.Item>
)}
>
{this.state.loading && this.state.hasMore && (
<div className="demo-loading-container">
<Spin />
</div>
)}
</List>
</InfiniteScroll>
</div>
);
}
}
ReactDOM.render(<InfiniteListExample />, mountNode);
.demo-infinite-container {
border: 1px solid #e8e8e8;
border-radius: 4px;
overflow: auto;
padding: 8px 24px;
height: 300px;
}
.demo-loading-container {
position: absolute;
bottom: 40px;
width: 100%;
text-align: center;
}
import { List, message, Avatar, Spin } from 'hzero-ui';
import reqwest from 'reqwest';
import WindowScroller from 'react-virtualized/dist/commonjs/WindowScroller';
import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer';
import VList from 'react-virtualized/dist/commonjs/List';
import InfiniteLoader from 'react-virtualized/dist/commonjs/InfiniteLoader';
const fakeDataUrl = 'https://randomuser.me/api/?results=5&inc=name,gender,email,nat&noinfo';
class VirtualizedExample extends React.Component {
state = {
data: [],
loading: false,
}
loadedRowsMap = {}
getData = (callback) => {
reqwest({
url: fakeDataUrl,
type: 'json',
method: 'get',
contentType: 'application/json',
success: (res) => {
callback(res);
},
});
}
componentDidMount() {
this.getData((res) => {
this.setState({
data: res.results,
});
});
}
handleInfiniteOnLoad = ({ startIndex, stopIndex }) => {
let data = this.state.data;
this.setState({
loading: true,
});
for (let i = startIndex; i <= stopIndex; i++) {
// 1 means loading
this.loadedRowsMap[i] = 1;
}
if (data.length > 19) {
message.warning('Virtualized List loaded all');
this.setState({
loading: false,
});
return;
}
this.getData((res) => {
data = data.concat(res.results);
this.setState({
data,
loading: false,
});
});
}
isRowLoaded = ({ index }) => {
return !!this.loadedRowsMap[index];
}
renderItem = ({ index, key, style }) => {
const { data } = this.state;
const item = data[index];
return (
<List.Item key={key} style={style}>
<List.Item.Meta
avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
title={<a href="https://ant.design">{item.name.last}</a>}
description={item.email}
/>
<div>Content</div>
</List.Item>
);
}
render() {
const { data } = this.state;
const vlist = ({ height, isScrolling, onChildScroll, scrollTop, onRowsRendered, width }) => (
<VList
autoHeight
height={height}
isScrolling={isScrolling}
onScroll={onChildScroll}
overscanRowCount={2}
rowCount={data.length}
rowHeight={73}
rowRenderer={this.renderItem}
onRowsRendered={onRowsRendered}
scrollTop={scrollTop}
width={width}
/>
);
const autoSize = ({ height, isScrolling, onChildScroll, scrollTop, onRowsRendered }) => (
<AutoSizer disableHeight>
{({ width }) => vlist({ height, isScrolling, onChildScroll, scrollTop, onRowsRendered, width })}
</AutoSizer>
);
const infiniteLoader = ({ height, isScrolling, onChildScroll, scrollTop }) => (
<InfiniteLoader
isRowLoaded={this.isRowLoaded}
loadMoreRows={this.handleInfiniteOnLoad}
rowCount={data.length}
>
{({ onRowsRendered }) => autoSize({ height, isScrolling, onChildScroll, scrollTop, onRowsRendered })}
</InfiniteLoader>
);
return (
<List>
{
data.length > 0 && (
<WindowScroller>
{infiniteLoader}
</WindowScroller>
)
}
{this.state.loading && <Spin className="demo-loading" />}
</List>
);
}
}
ReactDOM.render(<VirtualizedExample />, mountNode);
.demo-loading {
position: absolute;
bottom: -40px;
left: 50%;
}
API#
List#
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
bordered | 是否展示边框 | boolean | false |
footer | 列表底部 | string|ReactNode | - |
grid | 列表栅格配置 | object | - |
header | 列表头部 | string|ReactNode | - |
itemLayout | 设置 List.Item 布局, 设置成 vertical 则竖直样式显示, 默认横排 | string | - |
loading | 当卡片内容还在加载中时,可以用 loading 展示一个占位 | boolean|object (更多) | false |
loadMore | 加载更多 | string|ReactNode | - |
locale | 默认文案设置,目前包括空数据文案 | object | emptyText: '暂无数据' |
pagination | 对应的 pagination 配置, 设置 false 不显示 | boolean|object | false |
size | list 的尺寸 | default | middle | 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 展示在列表元素最右侧 | string|ReactNode | - |
List.Item.Meta#
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
avatar | 列表元素的图标 | ReactNode | - |
description | 列表元素的描述内容 | string|ReactNode | - |
title | 列表元素的标题 | string|ReactNode | - |