Ant Design Empty 组件完全指南:空状态占位符的定制、内置图片与全局配置
【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design
空状态(Empty State)是数据密集型界面的必备要素。在 Ant Design(antd)中,Empty组件用于在"没有数据"或"全新场景"下给出友好提示,本文以官方文档 components/empty/index.en-US.md 为骨架,结合仓库源码深入讲解其 API、内置图片、自定义方式、全局 ConfigProvider 接入与 Design Token 样式体系,帮助你在项目中正确使用并深度定制空状态展示。
何时使用(When To Use)
官方文档明确了两种典型场景:
- 无数据时的友好提示:当列表、表格、下拉框等组件没有可展示的数据时,用空状态占位符代替空白区域,避免用户感到困惑。
- 全新场景下的引导:在"新用户刚进入、还没有任何内容"的场景中,用空状态配合操作按钮引导用户去创建第一条数据。
从源码看,Empty并非只能单独使用。在 components/config-provider/defaultRenderEmpty.tsx 中,Table、List、Select、TreeSelect、Cascader、Transfer、Mentions等组件在无数据时都会默认渲染Empty,因此掌握该组件也就掌握了上述组件的空状态统一开关。
基础用法
最简单的用法是不传任何 props,直接渲染:
import React from 'react'; import { Empty } from 'antd'; const App: React.FC = () => <Empty />; export default App;上面的代码等价于显式传入默认图片与默认描述:
<Empty> <Button>Create</Button> </Empty>从 components/empty/index.tsx 的实现可以看出,description未显式传入时,会回退到useLocale('Empty')读取的本地化文案(即 locale 文件中Empty.description字段,如 "No data"),因此语言环境切换后描述会自动跟随。
只显示图片、隐藏描述
当图片已足够表达语义、无需文字时,可将description设为false来关闭描述区域:
import React from 'react'; import { Empty } from 'antd'; const App: React.FC = () => <Empty description={false} />; export default App;对应源码中{des && <div className={${prefixCls}-description}>{des}</div>}的判断逻辑:description为false时描述节点不会被渲染。
API 详解
官方文档提供的EmptyAPI 如下:
| Property | Description | Type | Default | Version |
|---|---|---|---|---|
| description | Customize description | ReactNode | - | |
| image | Customize image. Will treat as image url when string provided | ReactNode | Empty.PRESENTED_IMAGE_DEFAULT | |
| imageStyle | The style of image | CSSProperties | - |
另有通用属性可参考 Common props(如className、style、prefixCls、rootClassName等,均可用于Empty)。
逐项说明与源码印证
- description:自定义描述内容,类型为
ReactNode。源码 components/empty/index.tsx 中的逻辑为typeof description !== 'undefined' ? description : locale?.description——未传时使用 locale 默认文案;传false则完全隐藏。描述还会被用作字符串图片的alt文本(typeof des === 'string' ? des : 'empty'),提升可访问性。 - image:自定义图片。当传入字符串时会被当作图片 URL 渲染为
<img>(源码typeof image === 'string'分支),当传入 ReactNode 时原样渲染。默认值为Empty.PRESENTED_IMAGE_DEFAULT。 - imageStyle:图片区域的样式(自 3.16.0 起支持),作用于
.ant-empty-image容器。结合image一起使用时,可通过设置高度、宽度来缩放自定义图片。
内置图片:PRESENTED_IMAGE_DEFAULT 与 PRESENTED_IMAGE_SIMPLE
Empty是一个复合组件(CompoundedComponent),挂载了两个静态属性,对应两套内置 SVG 图片:
Empty.PRESENTED_IMAGE_SIMPLE:极简风格小图(官方展示尺寸约 55×35),适合空间紧凑的场景,如表格、列表行内的空状态。Empty.PRESENTED_IMAGE_DEFAULT:默认大图(官方展示尺寸约 121×116),适合整页或大面积区域的空状态。
两套图片分别定义在 components/empty/empty.tsx(默认图)与 components/empty/simple.tsx(简图),均以内联 SVG 实现,无需额外网络请求。
使用简化图
import React from 'react'; import { Empty } from 'antd'; const App: React.FC = () => <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />; export default App;使用简化图时,源码会自动加上${prefixCls}-normal类名(image === simpleEmptyImg判断),渲染为"常规(normal)"尺寸样式。
内置图片的智能配色
值得注意的实现细节:两套内置 SVG 都不是写死的颜色。默认图在 empty.tsx 中读取token.colorBgBase,通过TinyColor计算亮度,深色背景下会自动降低透明度(opacity: 0.65)以适配暗色主题;简图在 simple.tsx 中基于colorFill、colorFillTertiary、colorFillQuaternary、colorBgContainer等主题 Token 计算边框色、阴影色与内容色,因此能随主题变量自动变化。
自定义空状态(Customize)
Empty支持完全自定义:自定义图片、描述和操作区(footer)。
import React from 'react'; import { Button, Empty, Typography } from 'antd'; const App: React.FC = () => ( <Empty image="https://gw.alipayobjects.com/zos/antfincdn/ZHrcdLPrvN/empty.svg" imageStyle={{ height: 60 }} description={ <Typography.Text> Customize <a href="#API">Description</a> </Typography.Text> } > <Button type="primary">Create Now</Button> </Empty> ); export default App;本例同时演示了三个要点:
- 字符串图片 + 尺寸控制:
image传入 URL 字符串,配合imageStyle={{ height: 60 }}控制图片高度(样式作用于.ant-empty-image容器,容器内的img默认height: 100%)。 - 富文本描述:
description传入任意 ReactNode,不再局限于纯文本。 - 子节点作为操作区:
<Empty>的子节点会被渲染到.ant-empty-footer中,用于放置"创建""新建"等引导按钮——这正是官方文档建议的"新场景引导"用法。
源码对应关系见 components/empty/index.tsx:
<div className={`${prefixCls}-image`} style={imageStyle}>{imageNode}</div> {des && <div className={`${prefixCls}-description`}>{des}</div>} {children && <div className={`${prefixCls}-footer`}>{children}</div>}通过 ConfigProvider 全局定制空状态
很多组件(Select、Table、List、Cascader、Transfer、TreeSelect、Mentions 等)在无数据时默认渲染Empty。借助ConfigProvider的renderEmpty属性,可以为整棵组件树统一替换空状态渲染:
import React, { useState } from 'react'; import { SmileOutlined } from '@ant-design/icons'; import { Cascader, ConfigProvider, Divider, List, Select, Space, Switch, Table, Transfer, TreeSelect } from 'antd'; const customizeRenderEmpty = () => ( <div style={{ textAlign: 'center' }}> <SmileOutlined style={{ fontSize: 20 }} /> <p>Data Not Found</p> </div> ); const App: React.FC = () => { const [customize, setCustomize] = useState(true); return ( <> <Switch unCheckedChildren="default" checkedChildren="customize" checked={customize} onChange={setCustomize} /> <Divider /> <ConfigProvider renderEmpty={customize ? customizeRenderEmpty : undefined}> <Space direction="vertical" style={{ width: '100%' }}> <h4>Select</h4> <Select style={{ width: 200 }} /> <h4>TreeSelect</h4> <TreeSelect style={{ width: 200 }} treeData={[]} /> <h4>Cascader</h4> <Cascader style={{ width: 200 }} options={[]} showSearch /> <h4>Transfer</h4> <Transfer /> <h4>Table</h4> <Table columns={[{ title: 'Name', dataIndex: 'name', key: 'name' }, { title: 'Age', dataIndex: 'age', key: 'age' }]} /> <h4>List</h4> <List /> </Space> </ConfigProvider> </> ); }; export default App;renderEmpty的实现位于 components/config-provider/defaultRenderEmpty.tsx,其内部逻辑展示了"不同组件使用不同空状态规格"的约定:
Table、List:使用Empty.PRESENTED_IMAGE_SIMPLE(简化图);Select、TreeSelect、Cascader、Transfer、Mentions:使用简化图并追加ant-empty-small类(${prefix}-small),进一步缩小图片尺寸,适配下拉面板等紧凑场景;Table.filter:返回null,由表格组件自身处理筛选空态。
也就是说,各组件默认已经对空状态做了"尺寸分级"的取舍,你可以在renderEmpty中按组件名(componentName)做更精细的差异化定制。
Design Token 与样式定制
Empty的样式基于 CSS-in-JS 与 Design Token 体系生成,样式入口为 components/empty/style/index.ts。
- 组件级 Token:
Empty的ComponentToken默认为空接口(无专用 Token),样式主要复用全局 alias Token:colorTextDescription(描述文字颜色)、opacityImage(图片透明度)、margin/marginXS/marginXL(间距)等。 - 图片高度派生:通过
mergeToken基于controlHeightLG计算三档图片高度:- 默认图高度:
controlHeightLG * 2.5; - normal 图高度(简化图):
controlHeightLG; - small 图高度(下拉面板内):
controlHeightLG * 0.875。
- 默认图高度:
由此,调整全局基础 Token(如controlHeightLG)会同步影响空状态图片的整体视觉比例,也可以通过 Theme 配置覆盖opacityImage、colorTextDescription等变量实现整体风格定制。
无障碍与 RTL
- 图片语义:字符串图片的
alt会取description文案(字符串时),否则回退为'empty';内置 SVG 也带有<title>(如 "empty image"、"Simple Empty"),便于屏幕阅读器理解。 - RTL 支持:当
ConfigProvider的direction为rtl时,Empty根节点自动添加${prefixCls}-rtl类,配合整体 RTL 布局正常工作(见 components/empty/index.tsx)。
使用建议
- 优先使用内置图片:默认图与简化图已适配明暗主题,无需额外资源;需要更小尺寸时优先
PRESENTED_IMAGE_SIMPLE。 - 字符串 vs ReactNode 图片:临时替换可用 URL 字符串,并配合
imageStyle控制大小;需要主题联动或复杂矢量图时,传自定义 ReactNode/SVG 组件。 - 全局统一优先于逐个定制:涉及多组件的空状态统一替换,使用
ConfigProvider renderEmpty,避免重复代码。 - 用 footer 引导操作:空状态不仅是"告知",更应配合
children中的按钮给出下一步行动入口,提升转化。
相关示例代码与测试均可在 components/empty/demo(basic、simple、customize、config-provider、description 五个官方示例)与 components/empty/tests中进一步查看验证。
【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考