antd
覆盖官方样式
找到要修改的官方默认的类名,使用 global 保护起来后再修改,相反,如果不使用 global 无法修改。
:global(.ant-btn-primary) {
background-color: red;
}
官方样式源码 的目录 es 下有各个组件的样式,比如按钮的样式主文件是 antd/es/button/style/index.js
封装组件
封装组件 Button 为经过权限过滤的按钮,如果没有权限则不显示

菜单
码云仓库 的分支 mytools 的提交 e760c1cf27480542d70ac6a2b471827115afdd26 中使用 antd.menu 制作了组件 src/component/Menu 其中通过配置文件 src/component/Menu/config.ts 将二维数组生成树形左侧菜单的数据,该组件中同时封装了多个功能
- 根据名称返回
@ant-design/icons图标组件的函数getIcon - 生成菜单项对象的函数
getAntdMenuItem - 将二维数组生成树形菜单的函数
generatMenuItemList,返回的结果应用到antd.Menu.items属性上即可
图标
根据名称获取图标
import React from 'react'
import * as Icons from '@ant-design/icons'
// 传入图标的名称,返回 antd 的图标
function getIcon(name?:string){
if(!name) return <></>
const customerIcons:{[key:string]:any} = Icons
const icon = customerIcons[name]
if(!icon) return <></>
return React.createElement(icon)
}
官方
Breadcrumb
2024年8月19日 10:00:32 官方案例面包屑的数据类型是 [{title: 路径名称}],在项目中封装面包屑的代码如下
export default {
/**
* 获取指定路由的全路径字符串数组,用于显示在 breadCrumb
* @param treeNodeList 树形菜单
* @param url 目标路径名称
* @param pathArr 初次调用传入空数组
* @returns
*/
getLeafPath: function getLeafPath(treeNodeList: Array<MyType.MenuItem>, url: string, pathArr: string[]): string[] {
if (!treeNodeList) return treeNodeList
for (const item of treeNodeList) {
pathArr.push(item.label)
if (item.url === url) return pathArr
if (item.children?.length) {
const list = getLeafPath(item.children, url, pathArr)
if (list?.length) return list
}
pathArr.pop()
}
return []
}
}
import { useEffect, useState } from 'react'
import { Breadcrumb } from 'antd'
import styles from './index.module.less'
import { useLocation } from 'react-router-dom'
import utils from '@/utils'
import { menuItems } from '../Menu/config'
function BreadCrumb() {
const { pathname } = useLocation()
const [breadCrumb, setBreadCrumb] = useState<{ title: string }[]>()
const getBreadCrumb = (stringArr: string[]): { title: string }[] => {
if (!stringArr || stringArr.length === 0) return []
const ret: { title: string }[] = []
stringArr.forEach(item => ret.push({ title: item }))
return ret
}
useEffect(() => {
const breadCrumbStringArr = utils.getLeafPath(menuItems, pathname, [])
setBreadCrumb(getBreadCrumb(breadCrumbStringArr))
}, [pathname])
return <Breadcrumb className={styles.breadcrumb} items={breadCrumb} />
}
export default BreadCrumb
Select
<Select>
{
cityList.map(item => {
return <Select.Option key={item.id} value={item.id}>item.name</Select.Option>
})
}
</Select>
Table
表格中的枚举
渲染函数的第一个参数是当前列的数据,第二个参数是当前行的数据
// 格式化表格中的日期时间类型
{
title: '更新时间',
dataIndex: 'updateTime',
key:'updateTime',
render(currentColVal, currentRowVal){
return formatDate(currentColVal)
}
}
// 设置表格中的枚举值
{
title:'菜单类型',
dataIndex: 'menuType',
key:'menuType',
render(menuType){
return {
1: '菜单',
2: '按钮',
3: '页面'
}[menuType]
}
}
Form
默认值
<Form form={form} initialValues={{menuState: 1}}>
</Form>
变动检测
可通过属性 shouldUpdate 检测某个表单项变动后执行业务逻辑,见官网介绍。动态加载表单项的案例如下

使用案例
import { Form } from 'antd'
const [form] = Form.useForm()
<Form form={form} labelCol={{ span: 3 }} labelAlign='right'>
</Form>
执行校验
执行校验的方法 validateFields 是异步方法,如果不使用 async+await ,需要用嵌套回调的方法写代码。即校验成功的后续代码都写在 then 里面。当校验不通过时逻辑会流到 catch 分支中。
const handleSubmitChanCalls = () => {
form
.validateFields()
.then(res => {
console.log('表单验证的结果是', res)
})
.catch(err => {
message.error('请查看报错提示,修复后重试!')
return
})
}
获取数据、清除
const formValues = form.getFieldsValue() // 获取表单数据
form.resetFields() // 重置表单
message
常规的使用要求必须在 react 组件中才能使用 message,如果要自己封装的 request.ts 中使用浏览器控制台会报错 Warning: [antd: message] Static function can not consume context like dynamic theme. Please use 'App' component instead.
为解决该问题需要做如下步骤
创建组件 src/utils/AntdGlobal.tsx,全部代码如下:
import { App } from 'antd'
import type { MessageInstance } from 'antd/es/message/interface'
import type { ModalStaticFunctions } from 'antd/es/modal/confirm'
import type { NotificationInstance } from 'antd/es/notification/interface'
let message: MessageInstance
let notification: NotificationInstance
let modal: Omit<ModalStaticFunctions, 'warn'>
export default () => {
const staticFunction = App.useApp()
message = staticFunction.message
modal = staticFunction.modal
notification = staticFunction.notification
return null
}
export { message, notification, modal }
在根组件 src/App.tsx 中导入并使用该组件
import './App.css'
import { RouterProvider } from 'react-router-dom'
import router from './router'
import { ConfigProvider, App as AntdApp } from 'antd'
import AntdGlobal from './utils/AntdGlobal'
function App() {
return (
<ConfigProvider
theme={{
token: { colorPrimary: '#ed6c00' }
}}
>
<AntdApp>
<AntdGlobal />
<RouterProvider router={router} />
</AntdApp>
</ConfigProvider>
)
}
export default App
在自己封装的 src/utils/request.ts 中使用
import { message } from './AntdGlobal'
message.info('xxxxxx')
那么可以同样的方法在业务组件中使用。
或者使用官方推荐的方法如下:
import { App } from 'antd'
function Login(){
const { message, notification, modal} = App.useApp()
message.info('xxxxx')
}
export default Login
全局配置
全局尺寸
下图是根据 官网介绍全局配置的文章 制作的项目全局配置,应用在 react-manager 的分支 mytools 的 commit:fb82569185eb4ae2f1e25494eb34f088d010d6cb

主题色
antd 提供自定义主题色的功能,通过 ConfigProvider 包裹 app 根组件
import './App.css'
import { RouterProvider } from 'react-router-dom'
import router from './router'
import { ConfigProvider } from 'antd'
function App() {
return (
<ConfigProvider
theme={{
token: { colorPrimary: '#ed6c00' }
}}
>
<RouterProvider router={router} />
</ConfigProvider>
)
}
export default App
