主题
ant 基本使用与下载(Day11 3/3)
本页对应 React + TypeScript + 医通项目,共 5 段视频,约 1 小时 14 分。
学习目标
- 能说明 TypeScript 中内置对象、包装对象及 BOM/DOM 内置类的类型差异,并能正确使用类型断言处理 DOM 元素获取结果。
- 能使用 Create React App 的 TypeScript 模板创建 React 项目,并完成 antd 的安装与基础引入。
- 能按文档步骤在 React 组件中引入并使用 antd 组件,完成按钮等基础组件的渲染。
- 能使用 ConfigProvider 配置 antd 主题主色等全局样式,并验证配置生效。
- 能按“查组件文档—查看示例源码—复制代码—导入依赖—查阅 API 定制属性”的套路使用 antd 组件。
- 能使用 Table 组件完成表格渲染,正确配置 columns、dataSource、rowKey,并使用 render 自定义列内容及补充 TypeScript 类型。
知识点
一、先明确 Ant Design 的定位
为什么需要:后台管理系统要快速搭出表格、表单、按钮等界面,如果每个都手写,成本高且风格不统一。Ant Design(antd)是阿里团队面向 React 的 UI 组件库,适合后台系统快速开发。
怎么想:前台页面通常要体现公司个性化视觉,一般由 UI 设计师定制;后台主要给运营、管理人员使用,重点是好用、美观、开发快,所以适合用现成组件库。转写稿里也强调:antd 不是“前台展示页”的万能方案,而是后台管理系统的效率工具。
怎么做:用 create-react-app 创建 TypeScript 版 React 项目,再安装 antd。
bash
npx create-react-app 05-antd --template typescript
cd 05-antd
npm start
npm install antd易错点:项目名不要用中文、大写字母、下划线等不规范命名;--template typescript 不能漏;安装依赖时出现黄色警告不一定要处理,可能是 antd 依赖与 React 版本匹配问题。
二、TS 内置类型与类型断言是前置知识
为什么需要:antd 项目使用 TS,入口文件里 document.getElementById('root') 的返回值可能是 HTMLElement | null,而 createRoot 需要确定的元素节点,所以要用类型断言。
怎么想:转写稿里反复区分“小 boolean”和“大 Boolean”:小写是基本类型,大写是包装对象/内置类,实际开发中基本类型字面量更常用。DOM、BOM 内置对象在 TS 中也有对应类型,如 HTMLElement、NodeList。
怎么做:在入口文件中断言 root 一定存在:
tsx
const root = document.getElementById('root') as HTMLElement;
createRoot(root).render(<App />);易错点:断言只是“骗过 TS 编译阶段”,运行时如果元素不存在仍会报错;不要动不动写 any,能定义类型就定义类型;Boolean 与 boolean 不是同一个类型,实际业务多用 boolean。
三、安装后先跑通一个最小按钮
为什么需要:先验证 antd 是否安装成功、组件是否能正常渲染,再继续做复杂页面。
怎么想:按官方文档“在 create-react-app 中使用”的步骤走;组件从 antd 解构导入,图标从 @ant-design/icons 导入。
怎么做:在 App.tsx 中写最小示例:
tsx
import { Button } from 'antd';
function App() {
return <Button type="primary">按钮</Button>;
}
export default App;易错点:编辑器自动导入可能路径不对,转写稿里就出现过自动导入后仍需手动改成从 antd 引入;type="primary" 是 antd 按钮的颜色填充类型,不是 HTML 的按钮类型。
四、用 ConfigProvider 配置主题
为什么需要:项目通常要统一主色,不能每个按钮单独改样式。
怎么想:用 ConfigProvider 包裹根组件,通过 theme.token 配置全局主题变量。转写稿里演示包裹后按钮从蓝色变绿色。
怎么做:
tsx
import { ConfigProvider, Button } from 'antd';
function App() {
return (
<ConfigProvider theme={{ token: { colorPrimary: '#00b96b' } }}>
<Button type="primary">按钮</Button>
</ConfigProvider>
);
}易错点:主色写在 theme.token.colorPrimary,不是随便写 colorPrimary;要包裹根组件才能全局生效;主题可配置项很多,优先查文档复制,不必手敲。
五、antd 组件使用套路
为什么需要:antd 组件多,掌握套路比死记属性更有效。
怎么想:组件页 → 找组件 → 看代码演示 → 显示源代码 → 复制 → 导入组件 → 查 API 做高级配置。
怎么做:以 Button 为例:
tsx
import { Button } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
<Button type="primary" danger block>删除</Button>
<Button type="primary" icon={<SearchOutlined />}>搜索</Button>
<Button type="primary" loading={loading} onClick={() => setLoading(!loading)}>
切换 loading
</Button>易错点:danger 通常要配合 type="primary" 才有红色填充;提交按钮要用 htmlType="submit",因为 antd 的 type 已被用于颜色;loading 常配合 useState;图标库要从 @ant-design/icons 导入。
六、Table 渲染的三个核心配置
为什么需要:后台系统大量使用表格,必须理解 rowKey、columns、dataSource。
怎么想:columns 描述列,dataIndex 决定该列渲染数据源中的哪个字段,render 用于自定义单元格内容;dataSource 是数据数组;rowKey 指定唯一键。转写稿中把 key 改成 id 后报“each child in a list should have a unique key”,最后用 rowKey="id" 解决。
怎么做:
tsx
import { Table, Button } from 'antd';
import type { ColumnsType } from 'antd/es/table';
interface UserItem {
id: number;
name: string;
age: number;
address: string;
}
const columns: ColumnsType<UserItem> = [
{ title: '姓名', dataIndex: 'name' },
{ title: '年龄', dataIndex: 'age' },
{
title: '操作',
render: (_, row) => (
<Button type="primary" danger onClick={() => del(row.id)}>
删除
</Button>
),
},
];
<Table rowKey="id" columns={columns} dataSource={dataSource} />易错点:rowKey 必须唯一;render 有 dataIndex 时第一参是该字段值,没有 dataIndex 时第一参是当前行对象;ColumnsType 的泛型传“数组元素类型”,不是数组类型;不要用 any 逃避类型。
本节要解决什么
这一节的目标不是马上写复杂页面,而是把 Ant Design 相关依赖下载到 React + TypeScript 项目里,为后面使用按钮、图标、表格等组件做准备。转写稿里提到的“安T底赞”“安TD”“MTD”都应统一理解为 Ant Design,简称 antd。它是阿里团队面向 React 的后台管理系统 UI 组件库,适合快速搭建运营管理类页面。
为什么需要:后面要用 Button、Table 等组件,如果依赖没装好,代码里一导入就报错。
怎么想:先确认项目是 TypeScript 版 React 项目,再在项目根目录安装依赖,最后用一个小按钮验证是否生效。
怎么做:按本节笔记执行安装命令。
易错点:不要在错误目录安装;项目名不要用中文、大写字母或下划线;yarn 和 npm 不要在同一项目里混着锁文件用。
先准备 TypeScript 版 React 项目
转写稿中先创建的是 TypeScript 模板的 React 脚手架,命令是 create-react-app 项目名 --template typescript。创建完成后进入项目目录并启动。
为什么需要:antd 本身可以在 JS 项目里用,但本课程后面要讲类型、泛型、columns 类型等,所以项目必须是 TS 版。
怎么想:先有项目,再装依赖;不要在空目录里直接 yarn add antd 后就以为项目能跑。
怎么做:
shell
create-react-app 项目名 --template typescript
cd 项目名
npm start易错点:转写稿里启动后可能出现黄色版本警告,这类警告多来自 antd 依赖与当前 React 版本的匹配问题,初学阶段不要乱改 antd 内部封装;项目里的 .d.ts 声明文件也不要随意动。
安装 antd
本节笔记给出的核心命令是:
shell
yarn add antd
yarn add @ant-design/icons # 后面下载一下,增加提示功能为什么需要:antd 提供 Button、Table、ConfigProvider 等组件;没有它,import { Button } from 'antd' 会直接失败。
怎么想:安装命令要在项目根目录执行,也就是能看到 package.json 的那一层。笔记用 yarn,转写稿演示用 npm install antd,目的相同,选一种即可。
怎么做:在项目根目录执行 yarn add antd,安装完成后检查 package.json 的依赖项里是否出现 antd。
易错点:如果终端当前目录不对,依赖会装到别处;如果安装后编辑器仍报找不到模块,先确认终端所在目录,再重启 TS 服务或编辑器。
安装图标库
笔记第二行是:
shell
yarn add @ant-design/icons # 后面下载一下,增加提示功能为什么需要:转写稿后面讲按钮时,按钮可以带放大镜、问号等图标;这些图标不是从 antd 主包随便导入,而是从 @ant-design/icons 这个图标库导入。
怎么想:组件库和图标库分开安装,后面用图标时路径才不会写错。
怎么做:继续在项目根目录执行 yarn add @ant-design/icons。后面使用时从 @ant-design/icons 导入具体图标组件。
易错点:不要以为所有图标都从 antd 导入;转写稿明确说“所有的图标都从这个库里导”。如果忘了库名,可以回看安装命令或项目依赖。
验证安装:先跑出一个 Button
安装完不能只看终端“成功”二字,最好按转写稿的方式在 App.tsx 里引入一个按钮验证。转写稿中引入后出现蓝色按钮,说明 antd 生效。
为什么需要:验证依赖、导入路径、组件渲染是否都正常。
怎么想:先用最小代码测试,不要一上来就写复杂表格。
怎么做:在 App.tsx 中写类似:
tsx
import { Button } from 'antd';
function App() {
return <Button type="primary">按钮</Button>;
}
export default App;保存后刷新页面,能看到主色按钮即可。转写稿中 type="primary" 用来指定按钮的主色填充样式。
易错点:如果编辑器自动导入路径不对,要手动改成从 antd 导入;如果按钮没样式,先检查是否真的执行了安装、是否在项目根目录启动。转写稿中还提到主题配置用 ConfigProvider,这属于后续主题配置内容,本节先把“下载 + 能渲染 Button”跑通即可。
本节要解决什么问题
这一节的目标不是讲 antd 的所有组件,而是先把“antd 怎么在 TS 版 React 项目里用起来”跑通:项目里安装 antd,入口文件处理样式,在 App.tsx 里按需引入组件和图标,最后能在页面上看到组件生效。
为什么需要:antd 是后台管理系统常用的 UI 组件库,组件已经封装好,能减少重复写样式和交互的成本。
怎么想:先保证项目能启动,再装 antd,再处理样式,最后在组件里引入并使用。
怎么做:按“创建项目 → 安装 antd → 入口引入样式 → 组件中引入使用”的顺序做。
易错点:不要把 antd 组件和图标混在一起引;旧版样式引入和新版是否还需要引入 CSS 要按当前版本文档确认。
安装 antd 并准备 TS 版 React 项目
转写稿里反复提到“安T底赞”“MTD”,实际都是 Ant Design / antd;“re”是 React,“TS”是 TypeScript。先用 create-react-app 创建 TS 模板项目,再进入目录启动:
bash
create-react-app 项目名 --template typescript
cd 项目名
npm start项目跑起来后,再安装 antd:
bash
npm install antd为什么需要:不安装依赖,import { Button } from 'antd' 就找不到模块。
怎么想:先让脚手架项目正常启动,再装 UI 库,避免把“项目本身启动失败”和“antd 没装好”混在一起排查。
怎么做:在项目根目录执行安装命令,安装完成后按文档在组件里引入。
易错点:项目名不要用中文、不要用大写字母;安装后出现一些版本警告不一定要手改,转写稿里也提到 antd 内部依赖封装好的版本,先按文档跑通为主。
在入口文件处理 antd 样式
笔记里的 index.ts 是入口样式处理:
js
import 'antd/dist/antd.css' # 引入antd的css样式
// import 'antd/dist/antd.min.css'
// 新版不需要引入css了为什么需要:旧版 antd 的组件样式依赖全局 CSS,不引入可能出现按钮没有样式、表格排版错乱。
怎么想:先看当前 antd 版本文档。转写稿明确说“现在是 5.0”“新版不需要引入 css 了”,所以新版项目不要机械照抄旧写法。
怎么做:旧项目按文档引入 antd/dist/antd.css;新版按官方文档直接使用组件即可。
易错点:笔记里的 # 只是记录注释,不是 TypeScript 合法注释;真实代码注释要用 //。另外不要同时引入 antd.css 和 antd.min.css,二选一即可。
在 App.tsx 引入组件与图标
笔记里的 App.tsx 写法是:
js
import {Button, Table} from 'antd' //引入需要用的antd组件
import {SearchOutlined} from '@ant-design/icons' // 引入图标组件为什么需要:antd 组件很多,按需引入能让代码意图清楚;图标是独立包,不能直接从 antd 里随便解构。
怎么想:先确定页面要用 Button、Table,就从 antd 引入;要用放大镜图标 SearchOutlined,就从 @ant-design/icons 引入。
怎么做:在 App.tsx 顶部写 import,再在 JSX 里使用,例如按钮上配置 icon={<SearchOutlined />}。
易错点:图标名不要写错;如果图标包依赖未就绪,按官方文档补齐,不要自己造路径。转写稿还提到从文档复制示例后经常少导入,看到报错先检查“组件从哪来、图标从哪来”。
组件使用与调试套路
转写稿总结的套路很实用:到 antd 文档找组件 → 看代码演示 → 复制需要的示例 → 补上对应 import → 再看 API 调属性。比如按钮想变成带图标、带颜色、禁用、加载中,都不是手写 CSS 硬改,而是查 Button 的 API。
为什么需要:直接抄整段示例容易带入无关代码;只看效果不看 API 又不知道怎么改。
怎么想:先复制最小可用代码,再根据 API 加属性。
怎么做:例如 Button 的 type="primary" 控制主按钮,icon 放图标组件;Table 则至少要配 columns 和 dataSource,columns 里的 title 是表头,dataIndex 指定渲染数据源里的哪个字段,rowKey 指定每行唯一值。
易错点:Table 的 columns 类型在 TS 里要用 ColumnsType 配合泛型;没有唯一 rowKey 时列表渲染会警告。先跑通再优化类型,不要一开始被类型报错卡住。
课堂画面





代码示例
示例 1:Button 基本使用(App.tsx)
tsx
// 前提:create-react-app 创建 TS 模板项目
// npx create-react-app 05-antd --template typescript
// yarn add antd
// yarn add @ant-design/icons
import { useState } from 'react'
import { Button } from 'antd'
import { SearchOutlined } from '@ant-design/icons'
function App() {
// loading 受控状态
const [loading, setLoading] = useState<boolean>(false)
return (
<div style={{ padding: 20 }}>
{/* 主色填充按钮 + 放大镜图标 */}
<Button type="primary" icon={<SearchOutlined />}>
搜索
</Button>
{/* block:按钮宽度撑满父容器 */}
<Button type="primary" block icon={<SearchOutlined />}>
搜索
</Button>
{/* danger:只把颜色变红,不加 type 就没有背景填充 */}
<Button type="primary" danger>
删除
</Button>
{/* 没有文字、只有图标的圆形按钮 */}
<Button type="primary" shape="circle" icon={<SearchOutlined />} />
{/* loading 与状态联动:点一下转,再点一下不转 */}
<Button
type="primary"
loading={loading}
onClick={() => setLoading(!loading)}
>
change loading
</Button>
</div>
)
}
export default App要点解释与易错点
import { Button } from 'antd':antd 的组件从antd解构,图标组件必须从@ant-design/icons导入,两个库位置不同,混了会报错。type="primary"决定的是“按钮的颜色填充样式”,而原生表单的type="submit"在 antd 里被改名为htmlType="submit",写type="submit"是没有提交效果的。danger只负责把颜色变成红色,如果不写type="primary",就只是个红字按钮,没有红色背景。icon={<SearchOutlined />}是 JSX 插值,不是字符串,不能写icon="SearchOutlined"。shape="circle"要配合“没有文字、只有图标”使用,否则会变成一个椭圆。loading是布尔值,转写稿里强调:正常项目里用useState(false)控制,发请求前置true、请求回来置false。- 老版本 antd 需要在
index.ts里import 'antd/dist/antd.css';antd 5.x 已不需要引入该 CSS 文件,按笔记里的说明判断自己的版本。
示例 2:Table 渲染(TableTest.tsx)
tsx
import { Table, Button } from 'antd'
import type { ColumnsType } from 'antd/es/table'
// 先定义数据源数组里“每一项”的类型
interface IUserItem {
id: number
name: string
age: number
address: string
}
type IUserList = IUserItem[]
function TableTest() {
const dataSource: IUserList = [
{ id: 1, name: '胡彦斌', age: 32, address: '西湖区湖底公园1号' },
{ id: 2, name: '胡彦祖', age: 42, address: '西湖区湖底公园1号' }
]
const del = (id: number) => {
console.log('删除的 id:', id)
}
// ColumnsType 的泛型传的是“数组里每一项”的类型
const columns: ColumnsType<IUserItem> = [
{ title: '姓名', dataIndex: 'name' },
{ title: '年龄', dataIndex: 'age' },
{ title: '地址', dataIndex: 'address' },
{
title: '操作',
dataIndex: 'id',
// render 自定义该列渲染内容,return 什么就渲染什么
render: (value: number, row: IUserItem, index: number) => {
console.log(value, row, index)
return (
<Button type="primary" danger onClick={() => del(row.id)}>
删除
</Button>
)
}
}
]
return <Table rowKey="id" columns={columns} dataSource={dataSource} />
}
export default TableTest要点解释与易错点
- 渲染表格只需要配三个属性:
columns(列信息)、dataSource(数据源)、rowKey(唯一标识)。 rowKey="id"必须写:数据源里是id而不是key时,不写会报 “Each child in a list should have a unique key” 的警告。columns是数组,每一项是列配置对象:title是表头文字,dataIndex决定这一列渲染dataSource里的哪个字段。render是“当dataIndex满足不了需求”时的自定义渲染,return什么这一列就显示什么(这里 return 了两个按钮)。render的三个参数:value、row、index。易错点:value只有在配置了dataIndex时才是该字段的值(这里配置了id,所以value就是 id),没有dataIndex时value和row完全一样,都是当前行对象。- 点删除要传 id 时,从
row.id取最直观;若想从value取,dataIndex必须写成'id'。 - TS 环境下
render参数必须标类型,不能裸写;类型未定义前可以先用any顶住,类型定义好后再换回IUserItem/number。 ColumnsType<IUserItem>的泛型是数组里每一项的类型,不是IUserItem[],写成数组类型会报错;ColumnsType从antd/es/table导入。
示例 3:主题配置 + 入口(index.tsx)
tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import { ConfigProvider } from 'antd'
import App from './App'
// getElementById 返回 HTMLElement | null,createRoot 需要 HTMLElement
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
)
root.render(
<ConfigProvider
theme={{
token: {
colorPrimary: '#00b96b' // 主色,改成绿色
}
}}
>
<App />
</ConfigProvider>
)要点解释与易错点
ConfigProvider包裹的是根组件App,这样主题在整个项目里全局生效;只包裹某个组件则只对该组件生效。theme.token.colorPrimary改主色,此外还能配colorError、colorSuccess、colorWarning、文字大小等,具体键名查官方“定制主题”文档。- 这段配置一个项目只写一次,直接复制官方文档即可,不用手敲。
- 易错点:
document.getElementById('root')的返回类型是HTMLElement | null这样的联合类型,联合类型上不能直接使用元素属性,所以要as HTMLElement做类型断言。断言只是“骗过 TS 编译阶段的检查”,如果页面上真没有 id 为 root 的节点,运行阶段照样报错。 - 老版本 antd 才需要
import 'antd/dist/antd.css';5.x 不需要,多写这一行会直接报模块找不到。
常见错误
- 现象:按旧教程引入
antd/dist/antd.css后报路径错误或样式异常 → 原因:antd 5.x 与旧版样式引入方式不同 → 修法:先确认 antd 版本,5.x 不再按旧方式引入全局 CSS,按当前文档配置主题。 - 现象:表单里
<Button type="primary">提交</Button>点击不提交 → 原因:把视觉type当成原生按钮类型 → 修法:视觉用type,提交行为用htmlType="submit"。 - 现象:Table 控制台提示每行缺少唯一 key → 原因:
dataSource无key且未指定rowKey→ 修法:设置rowKey="id"或rowKey={(record) => record.id}。 - 现象:
columns写ColumnsType<IUserItem[]>或直接any后类型仍不对 → 原因:泛型应传“行对象类型”,不是数组类型 → 修法:写ColumnsType<IUserItem>。 - 现象:
render中以为value一定是整行对象,删除时取不到id→ 原因:配置了dataIndex后value是该字段值,不是整行 → 修法:需要整行用第二个参数record,需要字段值再配合dataIndex。 - 现象:
ConfigProvider配了主题但部分页面不生效 → 原因:只包裹了局部组件 → 修法:包裹根组件或需要生效范围的共同父级。 - 现象:图标组件从
antd导入失败 → 原因:图标在独立包中 → 修法:从@ant-design/icons导入。 - 现象:开发环境日志/渲染出现两次 → 原因:
StrictMode开发期检查 → 修法:确认非业务 bug,按需保留或移除严格模式。
练习
- 用 Create React App 的 TypeScript 模板创建项目,安装
antd与@ant-design/icons,在页面显示一个带搜索图标的按钮。 - 用
ConfigProvider修改主色,并验证包裹根组件与只包裹局部组件时的生效范围差异。 - 实现一个按钮:点击后在
loading状态间切换;另加一个htmlType="submit"的提交按钮和一个href跳转按钮。 - 用 Table 渲染用户列表,包含姓名、年龄、地址、操作列;设置
rowKey="id",操作列用render输出删除按钮并传入当前行id。 - 为 Table 的
dataSource和columns补充 TypeScript 类型,要求不使用any,并说明render的value、record、index各自适用场景。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 内置类-BOM-DOM内置类 | 12:44 |
| 2 | antd安装使用步骤 | 14:23 |
| 3 | 主题风格配置 | 03:19 |
| 4 | antd组件使用套路 | 16:44 |
| 5 | Table组件渲染 | 27:00 |
小结
- 先确认 antd 版本,再决定样式引入与主题配置方式,避免照搬旧教程。
- antd 组件使用优先走“选组件→看示例→复制→补导入→查 API”的路径。
- Button 的
type管视觉,htmlType管原生提交行为,二者不要混用。 - Table 渲染重点检查
rowKey、columns、dataSource三件事。 ColumnsType的泛型是行对象类型,不是行对象数组类型。render中需要整行数据时用record,不要误把value当整行。- 图标从
@ant-design/icons导入,主题全局生效要靠ConfigProvider包裹范围。 - TypeScript 项目中优先定义接口和具体类型,少用
any掩盖问题。