
Ant Design Drawer 基础抽屉实战从右侧滑出的受控面板与完整 API 解析【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design抽屉Drawer是 Ant Design 中用于承载临时任务与附加内容的浮层组件。本文以仓库中的「基础抽屉」官方示例components/drawer/demo/basic-right.md 及其配套代码 components/drawer/demo/basic-right.tsx为骨架讲解如何实现点击按钮抽屉从右滑出、点击遮罩区关闭这一最典型的应用场景并向下深挖组件源码、测试用例与全部 API 参数帮助你从能跑通示例进阶到理解抽屉的完整行为模型。基础抽屉最小可运行实现官方示例的核心语义是基础抽屉点击触发按钮抽屉从右滑出点击遮罩区关闭。完整代码如下摘自 basic-right.tsximport React, { useState } from react; import { Button, Drawer } from antd; const App: React.FC () { const [open, setOpen] useState(false); const showDrawer () { setOpen(true); }; const onClose () { setOpen(false); }; return ( Button typeprimary onClick{showDrawer} Open /Button Drawer titleBasic Drawer onClose{onClose} open{open} pSome contents.../p pSome contents.../p pSome contents.../p /Drawer / ); }; export default App;这个示例虽然短小却覆盖了 Drawer 的核心使用范式可拆解为三个要点受控开关open属性决定抽屉是否可见由useState(false)维护。点击按钮调用showDrawer将open置为true抽屉即从右侧滑出。关闭回调onClose在点击遮罩层、点击关闭图标或按 Esc等场景被触发回调中把open置回false。onClose只负责通知真正关闭仍需你同步状态这是典型的受控组件设计。内容区title渲染标题栏children三个p占位内容渲染在面板主体区域。从 v5 开始控制开关的受控属性统一为open。v4 时代的visible已被标记为 deprecateddeprecated Please use open insteadafterVisibleChange亦被afterOpenChange取代见 components/drawer/index.tsx 的类型定义。点击遮罩关闭与 Esc 关闭的行为模型示例描述点击遮罩区关闭并非魔法而是由两个默认值驱动的mask默认true是否展示遮罩层。示例未显式传入因此默认有半透明遮罩。maskClosable默认true点击蒙层是否允许关闭。示例未显式传入因此点击遮罩会触发onClose。keyboard默认true是否支持键盘Esc关闭。也就是说基础示例点击遮罩区关闭完全来自默认参数如果你希望遮罩不可点击关闭只需显式设置maskClosable{false}。需要无遮罩模式时可参考仓库中的 no-mask.md 演示对应源码中no-mask: !mask的类名拼接见 components/drawer/index.tsx。滑出方向与尺寸默认从右、默认 378px示例标题为基础抽屉之所以从右滑出是因为placement的默认值为right。可取值有top/right/bottom/left官方另提供 placement.md 演示用Radio.Group动态切换四个方向const [placement, setPlacement] useStateDrawerProps[placement](left); // ... Drawer titleBasic Drawer placement{placement} closable{false} onClose{onClose} open{open}方向与尺寸的搭配规则如下right/left时使用width控制宽度top/bottom时使用height控制高度。width默认378height默认378单位像素也支持字符串如50%。预设尺寸sizedefault378px或large736px优先级低于显式传入的width/height。这一合并逻辑在源码中有清晰的体现components/drawer/index.tsxconst mergedWidth React.useMemostring | number( () width ?? (size large ? 736 : 378), [width, size], ); const mergedHeight React.useMemostring | number( () height ?? (size large ? 736 : 378), [height, size], );即显式width/height优先未传时按size取large: 736或default: 378。预设宽度的演示见 size.md。Drawer 完整 API 参数速查下表完整继承自官方文档 components/drawer/index.zh-CN.md并结合源码补充了默认值与版本说明参数说明类型默认值版本autoFocus抽屉展开后是否将焦点切换至其 DOM 节点booleantrue4.17.0afterOpenChange切换抽屉时动画结束后的回调function(open)-classNameDrawer 容器外层 className 设置如需设置最外层请使用 rootClassNamestring-classNames语义化结构 classNameRecordSemanticDOM, string-5.10.0closeIcon自定义关闭图标5.7.0 起设置为null或false可隐藏关闭按钮ReactNodeCloseOutlined /destroyOnClose关闭时销毁 Drawer 里的子元素booleanfalseextra抽屉右上角的操作区域ReactNode-4.17.0footer抽屉的页脚ReactNode-forceRender预渲染 Drawer 内元素booleanfalsegetContainer指定 Drawer 挂载的节点并在容器内展现false为挂载在当前位置HTMLElement | () HTMLElement | Selectors | falsebodyheight高度placement为top或bottom时使用string | number378keyboard是否支持键盘 esc 关闭booleantruemask是否展示遮罩booleantruemaskClosable点击蒙层是否允许关闭booleantrueplacement抽屉的方向top|right|bottom|leftrightpush多层 Drawer 的推动行为boolean | { distance: string | number }{ distance: 180 }4.5.0rootStyle最外层容器样式与style的区别是作用节点包括maskCSSProperties-size预设抽屉宽度或高度default 378px / large 736pxdefault | largedefault4.17.0styleDrawer 容器样式仅需设置内容部分请使用bodyStyleCSSProperties-styles语义化结构 styleRecordSemanticDOM, CSSProperties-5.10.0title标题ReactNode-loading显示骨架屏booleanfalse5.17.0openDrawer 是否可见boolean-width宽度string | number378zIndex设置 Drawer 的 z-indexnumber1000onClose点击遮罩层、关闭图标或取消按钮时的回调function(e)-drawerRender自定义渲染抽屉(node: ReactNode) ReactNode-5.18.0关于loading属性有一处官方明确的演进记录自5.17.0提供loading后5.18.0修复了设计失误将内置的 Spin 组件替换为 Skeleton 组件同时收窄了loading的类型范围仅接收 boolean。在源码 DrawerPanel.tsx 中可以看到loading为true时 body 内渲染的是 5 行 paragraph 的Skeleton{loading ? ( Skeleton active title{false} paragraph{{ rows: 5 }} className{${prefixCls}-body-skeleton} / ) : ( children )}面板结构header / body / footer 三段式抽屉内容面板由 DrawerPanel.tsx 组装结构固定为三段header当title或关闭按钮存在时渲染包含关闭图标closeIcon默认CloseOutlined /经useClosable合并、标题与右侧extra操作区仅有关闭按钮而无标题、无 extra 时会附加-header-close-only类见 DrawerPanel.tsx。body主体内容区默认渲染childrenloading时替换为 Skeleton。footer仅当传入footer属性时渲染页脚节点。三个区域都支持通过classNames语义化 className与styles语义化 style精确控制样式这正是 5.10.0 引入的 Semantic DOM 能力示例见 classNames.md。另注意官方提示v5 使用rootClassName与rootStyle配置最外层元素样式v4 的className/style语义改为作用于 Drawer 窗体本身以与 Modal 对齐。源码级原理尺寸合并、动画、push 与 zIndex在 components/drawer/index.tsx 中可以观察到Drawer是对rc-drawer的封装几个值得注意的实现细节动画配置maskMotion与panelMotion均设置了motionAppear / motionEnter / motionLeave且motionDeadline: 500其中面板动画按placement区分panel-motion-${motionPlacement}这解释了从右滑出的滑入动画来源index.tsx。多层抽屉推动push默认值为{ distance: 180 }defaultPushState当存在多层 Drawer 时下层会被向同方向推动 180px演示见 multi-level-drawer.md。zIndex 管理通过useZIndex(Drawer, rest.zIndex)获取层级并与zIndexContext.Provider联动保证 Drawer、Modal、Popover 等浮层之间的遮挡顺序正确。ContextIsolator渲染时用ContextIsolator form space隔离 Form 与 Space 上下文避免抽屉内容意外继承外层表单行为。废弃属性告警开发环境下会对visible、afterVisibleChange、headerStyle、bodyStyle、contentWrapperStyle、maskStyle、drawerStyle等旧属性逐一发出deprecated警告引导迁移到open、afterOpenChange、styles.*新写法index.tsx。测试如何验证基础抽屉仓库为抽屉组件维护了多层测试可作为行为契约参考demo.test.ts 通过demoTest(drawer)对所有 demo 做冒烟渲染保证示例可运行。demo-extend.test.tsx 在 mockrc-drawer强制open: true、getContainer: false、禁用动画后对 demo 进行更严格的交互测试。Drawer.test.tsx 覆盖了render correctly、getContainer返回 undefined/false、render top drawerplacementtop配height、RTL 方向等核心行为其中triggerMotion通过模拟遮罩与面板的animationEnd完成动画推进。这些测试共同印证了示例中的行为打开由open驱动、方向由placement决定、遮罩点击与 Esc 通过onClose通知状态更新。从基础示例出发的下一步基础抽屉解决的是临时任务浮层这一最小诉求。当业务场景变复杂时官方演示集还提供了成套方案均可在仓库中直接查看表单放入抽屉form-in-drawer.md信息预览型抽屉user-profile.md多层抽屉联动multi-level-drawer.md渲染在当前 DOMgetContainer{false}render-in-current.md预设宽度size.md掌握本文的基础范式受控openonClose回调 默认placementright 默认宽高 378px再配合完整 API 表与源码实现细节即可在项目中自如地驾驭这一从屏幕边缘滑出的浮层面板。【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考