- UI组件
- 前端
【免费下载链接】ng-zorro-antd
Angular UI Component Library based on Ant Design
导读
本文围绕 ng-zorro-antd 组件库中 Resizable(可调整尺寸)组件 的「栅格(Grid)」演示展开,讲解如何让拖拽缩放按 24 栅格列系统吸附、结合nz-col实现两列联动布局。读完本文,你将掌握nzGridColumnCount、nzMinColumn、nzMaxColumn三个栅格核心参数的使用方式、事件回调中col字段的计算逻辑,以及cursorType: 'grid'光标模式与nz-resize-handles的组合用法,并能在自己的 Angular 页面中直接复刻该联动布局。
一、演示文档与源码定位
官方演示文档 components/resizable/demo/grid.md 对该示例的描述非常简洁:「配合栅格使用 / Resize with grid.」——即把 Resizable 的缩放行为与 ng-zorro-antd 的 24 栅格系统(NzGridModule)整合:拖拽过程中元素宽度不是任意像素值,而是按栅格列(column)为单位跳变,从而保证布局始终对齐栅格。
其配套实现位于 components/resizable/demo/grid.ts,完整展示了该场景的最小可运行代码。组件库官方 API 文档位于 components/resizable/doc/index.en-US.md,其中[nzGridColumnCount]、[nzMinColumn]、[nzMaxColumn]正是栅格模式的核心输入属性。
二、栅格模式核心实现原理
栅格化的本质在指令 components/resizable/resizable.directive.ts 的calcSize方法中体现。该方法以nzGridColumnCount是否等于-1作为是否进入栅格模式的开关(源码见 resizable.directive.ts#L62-L63 与 resizable.directive.ts#L149-L153):
@Input({ transform: numberAttribute }) nzGridColumnCount: number = -1; @Input({ transform: numberAttribute }) nzMaxColumn: number = -1; @Input({ transform: numberAttribute }) nzMinColumn: number = -1;当nzGridColumnCount !== -1时,拖拽逻辑按以下三步处理:
- 计算单列宽度(spanWidth):
spanWidth = maxWidth / nzGridColumnCount,其中maxWidth是受边界(nzBounds)约束后的最大宽度,即把可缩放区域等分为nzGridColumnCount份; - 换算最小/最大列数:
minWidth = nzMinColumn !== -1 ? spanWidth * nzMinColumn : minWidth,maxWidth = nzMaxColumn !== -1 ? spanWidth * nzMaxColumn : maxWidth,将列数限制转换为像素限制; - 取整吸附:在尺寸计算完成后执行
col = Math.round(newWidth / spanWidth); newWidth = col * spanWidth;(resizable.directive.ts#L174-L177),保证最终宽度始终是单列宽度的整数倍。
计算完成后返回的事件对象中包含col字段:
interface NzResizeEvent { width?: number; height?: number; col?: number; mouseEvent?: MouseEvent | TouchEvent; direction?: NzResizeDirection; }该接口定义在 resizable.directive.ts#L31-L37,演示代码正是从nzResize事件中解构出col并驱动页面布局。
三、栅格联动布局:完整示例拆解
以 components/resizable/demo/grid.ts 为蓝本,一个「左列可拖拽、右列自动补位」的布局模板如下:
<div nz-row> <div class="col" nz-col nz-resizable (nzResize)="onResize($event)" [nzMinColumn]="3" [nzMaxColumn]="20" [nzGridColumnCount]="24" [nzSpan]="col()" > <nz-resize-handles [nzDirections]="directions()" /> col-{{ col() }} </div> <div class="col right" nz-col [nzSpan]="24 - col()">col-{{ 24 - col() }}</div> </div>对应组件逻辑:
export class NzDemoResizableGridComponent { readonly col = signal(8); id = -1; readonly directions = signal<NzResizeHandleOption[]>([ { direction: 'right', cursorType: 'grid' } ]); onResize({ col }: NzResizeEvent): void { cancelAnimationFrame(this.id); this.id = requestAnimationFrame(() => { this.col.set(col!); }); } }关键设计点:
- 双向联动:左列
nzSpan绑定col(),右列nzSpan绑定24 - col()。因为 24 栅格系统一行的span总和固定为 24,拖拽左列时右列自动补满剩余栅格,形成「此消彼长」的联动效果; - 拖拽方向与光标:
nz-resize-handles只声明了right方向,并将cursorType设为grid(NzResizeHandleOption接口定义见 resize-handles.component.ts#L21-L24)。cursorType: 'grid'会为手柄挂上nz-resizable-handle-cursor-type-grid类(见 resize-handle.component.ts#L53-L54),提示用户该手柄按栅格步进而非自由缩放; - 性能优化:
onResize中使用cancelAnimationFrame+requestAnimationFrame合并帧,避免高频拖拽事件导致频繁变更检测,这是演示代码中值得借鉴的实践。
四、栅格参数详解与默认值
结合 components/resizable/doc/index.en-US.md 的 API 表与 resizable.directive.ts 源码,栅格模式相关参数如下:
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
[nzGridColumnCount] | 栅格列数,设为-1表示不启用栅格模式 | number | -1 |
[nzMinColumn] | 可缩放的最小列数 | number | -1(不限制,退化为像素级nzMinWidth) |
[nzMaxColumn] | 可缩放的最大列数 | number | -1(不限制) |
[nzBounds] | 缩放边界,可选'window' \| 'parent' \| ElementRef<HTMLElement> | - | 'parent' |
[nzMinWidth]/[nzMinHeight] | 像素级最小宽/高,栅格模式下未设置列限制时兜底使用 | number | 40 |
(nzResize) | 拖拽过程中触发,事件含col字段 | EventEmitter<NzResizeEvent> | - |
使用建议:
nzGridColumnCount通常与 Ant Design 栅格系统的 24 列保持一致,即设为24,与nz-col的nzSpan语义对齐;- 设置了列数限制(
nzMinColumn/nzMaxColumn)后,像素级nzMinWidth/nzMaxWidth会被列宽覆盖(resizable.directive.ts#L151-L152); - 拖拽中拿到的事件
col是经过Math.round四舍五入后的整数,可直接用于nzSpan绑定。
五、测试用例验证栅格行为
仓库自带单元测试 components/resizable/resizable.spec.ts 的griddescribe 块(resizable.spec.ts#L531-L589)直接复用了NzDemoResizableGridComponent演示组件,验证了两个关键行为:
- 列数限制生效:向左拖拽到极限时
expect(testComponent.col()).toBe(3),即宽度被nzMinColumn拦截至 3 列;向右拖拽到极限时expect(testComponent.col()).toBe(20),即被nzMaxColumn限制在 20 列(resizable.spec.ts#L543-L576); - 光标类型切换:
cursorType: 'grid'时元素上存在nz-resizable-handle-cursor-type-grid类而不存在-window类,切换为'window'后类名随之翻转(resizable.spec.ts#L578-L589)。
测试通过模拟mousedown+ 文档级mousemove/mouseup事件链来驱动缩放流程——这正是NzResizableService的运行时行为:手柄mousedown后,服务在 document 上挂载mousemove/mouseup监听器,并在runOutsideAngular中执行以降低变更检测开销(见 resizable.service.ts#L34-L55)。因此测试与真实交互共享同一套事件管线,验证结论对实际行为具备较强说服力。
六、样式定制
栅格模式不引入额外样式,手柄外观由组件库内置的.nz-resizable-handle系列类控制(style)。官方文档建议通过覆盖以下类来定制(见 components/resizable/doc/index.en-US.md 的 Styling 一节):
.nz-resizable:nz-resizable指令命名空间;.nz-resizable-handle:手柄命名空间,含 8 个方向类(-top、-right、-bottom、-left、-topRight、-bottomRight、-bottomLeft、-topLeft);.nz-resizable-handle-cursor-type-grid:栅格光标类型命名空间,演示中拖拽手柄即使用该类。
需要单独引入组件样式时,可在全局样式中加入:
@import 'node_modules/ng-zorro-antd/resizable/style/entry.less';七、进阶提示
- 栅格模式可与 nzPreview(预览幽灵元素)配合使用,拖拽时先展示吸附后的栅格尺寸再落位,视觉反馈更直观;
- 演示中的
requestAnimationFrame节流模式适用于所有 Resizable 场景(basic.ts 同样采用该写法),建议在实际项目中保留; - 若需要更多拖拽方向(如左右双向),只需扩展
nzDirections数组,每个元素可以是NzResizeDirection字符串或NzResizeHandleOption对象,字符串会被规范化为cursorType: 'window'(见 resize-handles.component.ts#L26-L37)。
总结
ng-zorro-antd Resizable 的栅格模式通过「列数 → 像素 → 取整吸附」三步转换,把自由拖拽约束到 24 栅格体系内,配合nz-col的 span 联动即可构建出对齐规范、体验良好的可调布局。核心参数nzGridColumnCount/nzMinColumn/nzMaxColumn的语义、事件col字段的计算方式,以及源码与测试中的验证路径,已在本文完整展开,可直接对照 演示源码 与 核心指令 落地实践。
- UI组件
- 前端
【免费下载链接】ng-zorro-antd
Angular UI Component Library based on Ant Design
相关推荐
ng-zorro-antd Grid 栅格布局系统完全指南:24 栅格原理、Flex 排列与响应式断点实战
ng zorro antd Grid 栅格布局系统完全指南:24 栅格原理、Flex 排列与响应式断点实战 本指南以 ng zorro antd 组件库中的 G
UI组件前端ng-zorro-antd 栅格卡片实战:用 Card 与 Grid 24 栅格体系搭建系统概览页
ng zorro antd 栅格卡片实战:用 Card 与 Grid 24 栅格体系搭建系统概览页 在系统概览类页面中,"卡片 + 栅格列"是最经典的组合形态:
UI组件前端ng-zorro-antd 基础栅格(Basic Grid)实战指南:用 nz-row 与 nz-col 构建 24 栅格布局
ng zorro antd 基础栅格(Basic Grid)实战指南:用 nz row 与 nz col 构建 24 栅格布局 ng zorro antd 的
UI组件前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考