十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

NocoBase SortHandle 组件详解:Table 拖拽排序手柄的用法与底层原理

NocoBase SortHandle 组件详解:Table 拖拽排序手柄的用法与底层原理 NocoBase SortHandle 组件详解Table 拖拽排序手柄的用法与底层原理【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobaseSortHandle是 NocoBasenocobase/client-v2包中Table组件拖拽排序功能的核心拖拽手柄drag handle它通过dnd-kit/sortable提供的 activator 能力触发整行拖拽。本文基于 sort-handle.md 并结合 client-v2 源码讲解 SortHandle 的用法、API、与Table/SortableRow的协作机制以及自定制手柄列时的最佳实践。SortHandle 是什么SortHandle是Table拖拽排序的拖拽手柄。在 NocoBase 的设置页表格场景中拖拽排序是行级操作用户按住手柄默认是一行MenuOutlined图标将行拖到目标位置后松手onSortEnd(from, to)回调被触发由调用方持久化排序结果。从 源码实现 看SortHandle本身并不包含任何拖拽逻辑export const SortHandle: React.FC{ id?: string | number; style?: React.CSSProperties } (props) { const { id: _id, ...otherProps } props; const dragSortContext React.useContext(DragSortRowContext); return ( span ref{dragSortContext?.setActivatorNodeRef} {...dragSortContext?.attributes} {...dragSortContext?.listeners} {...otherProps} className{classNames(sortHandleClass)} MenuOutlined / /span ); };关键点在于它通过React.useContext(DragSortRowContext)读取父级行上下文把setActivatorNodeRef、attributes、listeners挂到自身span上从而成为行的拖拽激活点activator。因此SortHandle必须放在Table的可拖拽行上下文里单独渲染它不会触发拖拽。基本用法通常来说直接给 Table 传isDraggable就够了组件会自动在行首渲染一个手柄列只有当你要自己控制手柄所在列时才需要直接使用SortHandle。import { SortHandle, Table } from nocobase/client-v2; Table rowKeyid isDraggable showSortHandle{false} columns{[ { key: sort, width: 40, render: () SortHandle / }, ...columns, ]} /;这个示例的要点isDraggable开启拖拽排序能力Table内部会自动把components.body.row替换为SortableRow并用DndProviderSortableContext包裹表格主体showSortHandle{false}关闭Table默认自动插入的拖拽手柄列源码见 Table.tsx 中的showStandaloneHandleColumn判断你自己定义一个宽度为40的列在render中渲染SortHandle /手柄就出现在你指定的这一列里。SortHandle需要放在Table的可拖拽行上下文里。单独渲染它不会触发拖拽。工作原理DragSortRowContext 上下文链SortHandle之所以能躺着触发拖拽是因为它消费了由SortableRow提供的 DragSortRowContexttype DragSortRowContextValue { attributes?: DraggableAttributes; listeners?: SyntheticListenerMap; setActivatorNodeRef?: (node: HTMLElement | null) void; }; export const DragSortRowContext React.createContextDragSortRowContextValue | null(null);而SortableRow是 antd Tablecomponents.body.row的拖拽实现对应文档 sortable-row.md它使用useSortable({ id })建立行级拖拽能力并读取 antd 注入到tr上的data-row-key作为排序 idconst id props[data-row-key]?.toString(); const { setNodeRef, setActivatorNodeRef, attributes, listeners, active, over } useSortable({ id });随后它用DragSortRowContext.Provider把listeners、attributes、setActivatorNodeRef提供给行内的所有后代组件DragSortRowContext.Provider value{{ listeners, attributes, setActivatorNodeRef }} tr ref{(node) { setNodeRef(node); }} {...others} className{...} / /DragSortRowContext.Provider这样SortHandle就可以放在行的任意单元格中通常是专门的第一列而不必非得是整个行都可拖拽。整条链路是Table开启isDraggable后tableComponents将components.body.row替换为SortableRowTable.tsxTable用DndProviderSortableContext items{itemKeys}包裹表格itemKeys由rowKey从dataSource逐行读取生成Table.tsx行渲染时SortableRow通过useSortable注册自己并通过 Context 把拖拽能力下发给SortHandle用户按住SortHandle拖动Table的handleDragEnd解析from/to记录并调用onSortEnd(from, to)Table.tsx。组件还通过DndProvider来自nocobase/flow-engine暴露的onDragStart在拖拽开始时用snapshotSourceRow快照源tr配合DragOverlay渲染行拖拽预览Table.tsx拖拽过程中行高亮使用主题色token.colorPrimary生成上下边框指示落点SortableRow.tsx。APISortHandle的对外参数如下参数类型说明idstring \| number保留参数当前不会参与渲染styleReact.CSSProperties自定义样式其中id在源码中被显式解构为_id后丢弃const { id: _id, ...otherProps } props即它是为未来扩展预留的参数目前不影响任何行为。style等其余 props 会通过...otherProps透传到内部span上可用于自定义手柄的大小、颜色、间距等。与其他组件的协作与Table的协作Table在isDraggable开启时按以下规则决定手柄渲染位置Table.tsx有rowSelection且showSortHandle为真手柄渲染在选择列单元格内showHandleInSelection无rowSelection且showSortHandle为真自动在行首插入一个宽度为sortHandleColumnWidth默认40的独立手柄列showStandaloneHandleColumn列的render直接返回SortHandle /Table.tsxshowSortHandle{false}不渲染任何默认手柄完全由你自定义。也就是说文档示例中showSortHandle{false}加自定义列的方式本质上是把手柄放哪一列的控制权从Table手里拿回来。与SortableRow的协作SortHandle和SortableRow定义在同一个文件 SortableRow.tsx 中并通过packages/core/client-v2/src/components/form/table/dnd/index.ts统一导出。在 flow 引擎的表格模型里这两个组件也被复用dragSortComponents.tsx直接 re-exportDragSortRowContext、SortHandle、SortableRow而 dragSortHooks.tsx 中的useDragSortBodyWrapper会用DndProviderSortableContext包裹tbody并在拖拽结束时调用resource.runAction(move, { sourceId, targetId, sortField })完成服务端排序持久化随后resource.refresh()刷新列表。相关链接Table — 设置页表格isDraggable开启拖拽排序SortableRow — antd Table body row 的拖拽实现为SortHandle提供拖拽上下文【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表