如何基于Ant Design 5+ Design Token为自定义组件适配多屏幕尺寸
在Ant Design 5+中实现自定义组件的响应式宽高(仿Grid组件参数)
核心思路
Ant Design 5的响应式体系基于内置断点系统,我们可以利用useBreakpoint Hook获取当前屏幕的断点激活状态,再结合传入的xs/sm/md/lg/xl/xxl参数,动态设置自定义组件的宽高,完全复刻Grid组件的响应式逻辑。
实现步骤与代码示例
1. 基础响应式组件实现
这个组件支持传入数字(宽高一致)或对象(自定义宽高)类型的断点参数,自动匹配当前屏幕尺寸:
import { useBreakpoint } from 'antd'; import React from 'react'; const ResponsiveBox = ({ xs, sm, md, lg, xl, xxl, children }) => { // 获取当前屏幕的断点激活状态(如{xs: true, sm: false, ...}) const breakpoints = useBreakpoint(); // 定义断点优先级:从大尺寸到小尺寸,确保优先匹配当前最大的激活断点 const breakpointPriority = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs']; // 找到当前生效的最高优先级断点 const currentBp = breakpointPriority.find(bp => breakpoints[bp]); // 获取对应断点的尺寸参数,默认用xs兜底 const sizeConfig = { xxl, xl, lg, md, sm, xs }[currentBp] || xs; // 解析尺寸:数字则宽高一致,对象则分别取width/height const width = typeof sizeConfig === 'number' ? sizeConfig : sizeConfig?.width; const height = typeof sizeConfig === 'number' ? sizeConfig : sizeConfig?.height; return ( <div style={{ width, height, border: '1px solid #e8e8e8', display: 'flex', alignItems: 'center', justifyContent: 'center' }} > {children} </div> ); }; // 使用示例 const Demo = () => { return ( <ResponsiveBox xs={120} sm={{ width: 220, height: 160 }} md={320} lg={{ width: 420, height: 260 }} xl={520} xxl={620} > 自适应盒子 </ResponsiveBox> ); }; export default Demo;
2. 结合Design Token统一管理尺寸
如果需要用Design Token管理所有响应式尺寸,避免硬编码,可以这样实现:
import { ConfigProvider, useBreakpoint, useToken } from 'antd'; import React from 'react'; // 自定义Design Token const customTheme = { token: { responsiveSizes: { xsBox: 120, smBox: { width: 220, height: 160 }, mdBox: 320, lgBox: { width: 420, height: 260 }, xlBox: 520, xxlBox: 620, }, }, }; const ResponsiveBox = ({ children }) => { const breakpoints = useBreakpoint(); const { token } = useToken(); const breakpointPriority = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs']; const currentBp = breakpointPriority.find(bp => breakpoints[bp]); const sizeConfig = token.responsiveSizes[`${currentBp}Box`] || token.responsiveSizes.xsBox; const width = typeof sizeConfig === 'number' ? sizeConfig : sizeConfig?.width; const height = typeof sizeConfig === 'number' ? sizeConfig : sizeConfig?.height; return ( <div style={{ width, height, border: '1px solid #e8e8e8', display: 'flex', alignItems: 'center', justifyContent: 'center' }}> {children} </div> ); }; // 全局注入Token后使用 const App = () => { return ( <ConfigProvider theme={customTheme}> <ResponsiveBox>自适应盒子</ResponsiveBox> </ConfigProvider> ); }; export default App;
3. 仿Grid组件的栅格化宽高
如果需要和Grid组件的span参数逻辑一致(基于24栅格计算宽度),可以结合useToken获取内置栅格列数:
import { useBreakpoint, useToken } from 'antd'; import React from 'react'; const ResponsiveGridBox = ({ xs, sm, md, lg, xl, xxl, children }) => { const breakpoints = useBreakpoint(); const { token } = useToken(); // 获取内置栅格列数,默认24 const gridColumns = token.gridColumns || 24; const breakpointPriority = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs']; const currentBp = breakpointPriority.find(bp => breakpoints[bp]); const spanConfig = { xxl, xl, lg, md, sm, xs }[currentBp] || xs; let width, height; if (typeof spanConfig === 'number') { // 按栅格比例计算宽度 width = `${(spanConfig / gridColumns) * 100}%`; height = 'auto'; // 可自定义默认高度 } else { // 支持传入自定义宽高对象 width = spanConfig?.width; height = spanConfig?.height; } return ( <div style={{ width, height, border: '1px solid #e8e8e8', display: 'flex', alignItems: 'center', justifyContent: 'center' }}> {children} </div> ); }; // 使用示例 const Demo = () => { return ( <ResponsiveGridBox xs={24} // 占满整行 sm={12} // 半行 md={8} // 1/3行 lg={6} // 1/4行 > 栅格化自适应盒子 </ResponsiveGridBox> ); }; export default Demo;
关键说明
useBreakpoint返回各断点的激活状态,比如屏幕宽度在md区间时,xs/sm/md均为true,通过从大到小遍历断点,确保优先匹配当前最大的生效断点- 支持两种参数格式:数字(宽高统一)、对象(自定义宽高),完全对齐Grid组件的参数设计
- 结合
useToken可无缝对接Design Token,实现全局尺寸的统一维护
内容的提问来源于stack exchange,提问作者V.Rashkov
相关产品推荐
相关产品推荐

