恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Tiptap 拖拽排序指南:从手柄显示到嵌套拖动的 5 个步骤
首页
资讯中心
/
Tiptap 拖拽排序指南:从手柄显示到嵌套拖动的 5 个步骤
Tiptap 拖拽排序指南:从手柄显示到嵌套拖动的 5 个步骤
发布时间:2026/9/1 10:45:52
Tiptap 拖拽排序指南从手柄显示到嵌套拖动的 5 个步骤【免费下载链接】tiptapThe headless rich text editor framework for web artisans.项目地址: https://gitcode.com/GitHub_Trending/ti/tiptap写长文档时用户总想把这一段挪到上面、这两个块换一下顺序。传统做法是剪切、粘贴、再找位置步骤又多又容易出错。Tiptap无头富文本编辑器框架的tiptap/extension-drag-handle扩展下称 DragHandle 扩展给编辑器加上了拖拽排序能力鼠标悬停在块级元素旁会出现拖拽手柄按住拖动即可完成排序。本文以你已有一个 Tiptap 编辑器为前提讲清楚拖拽排序如何跑起来、如何自定义、如何控制。一分钟跑通拖拽排序引入扩展并初始化编辑器先安装扩展然后把它放进编辑器的extensions数组即可npm install tiptap/extension-drag-handleimport { Editor } from tiptap/vue-3 import StarterKit from tiptap/starter-kit import { DragHandle } from tiptap/extension-drag-handle const editor new Editor({ content: p把我拖到上面/pp把我拖到下面/p, extensions: [ StarterKit, DragHandle.configure({ computePositionConfig: { placement: left-start }, }), ], })此时编辑器已经具备拖拽排序鼠标移到任意块级元素段落、标题等上其左侧出现拖拽手柄按住并移动即可完成重排。所有配置项的完整定义见 drag-handle.ts。React 写法的差异React 项目建议安装tiptap/extension-drag-handle-react用组件包裹手柄内容而不是往extensions数组里塞DragHandle editor{editor} nested div classNamecustom-drag-handle / /DragHandle这个组件内部自己注册 ProseMirror 插件并卸载实现见 DragHandle.tsx。⚠️ 如果在 React 项目里直接引入核心包的DragHandle却没有任何效果或报错先检查是不是该换用框架专用包。自定义手柄样式与位置换掉手柄的图标和外观默认手柄是一个 class 为drag-handle的div。它由render()方法生成你可以返回任意 DOM 节点DragHandle.configure({ render() { const handle document.createElement(div) handle.className custom-drag-handle handle.innerHTML ☰ return handle }, }).custom-drag-handle { width: 1.5rem; height: 1.25rem; background: #f0f0f0; border-radius: 4px; cursor: grab; }注意手柄不是编辑器文档里的子节点而是浮动在页面层、由 floating-ui一个定位工具库计算位置所以给它加样式没有任何限制。调整手柄的显示位置computePositionConfig就是 floating-ui 的配置对象默认placement为left-start块级元素左上方。想让手柄贴到右侧——比如配合从右到左RTL的排版——改一个字段即可把配置写成computePositionConfig: { placement: right-start }。 若手柄看起来错位或被容器裁掉优先检查两点placement是否符合预期以及编辑器内容区是否留出了左侧空间。示例项目里通过给内容元素加margin-inline-start腾出手柄位置如果你的容器没有留白手柄会溢出到可视区之外。启用嵌套内容拖动打开 nested 选项默认只有文档顶层的块级元素显示手柄。列表项、引用块这类嵌套内容想拖时启用nestedDragHandle.configure({ nested: { allowedContainers: [bulletList, orderedList, blockquote], }, })nested也可以直接传true使用内置默认行为或者像上面这样用allowedContainers限定哪些容器内的元素可被拖动。用评分规则微调拖拽目标启用嵌套后内部会有一套规则评分机制对光标位置的所有祖先节点打分选出最合适的拖拽目标。默认规则在 defaultRules.ts你也可以加自己的规则例如给codeBlock打高分让它几乎不会被误拖动。监听拖拽事件与锁定手柄拖拽开始、结束与悬停回调需要把排序结果同步到后端或记录历史时配置回调即可DragHandle.configure({ onElementDragStart: () markDragging(true), onElementDragEnd: () persistOrder(editor), onNodeChange: ({ node }) highlight(node), // node 为 null 表示未悬停 })拖拽的完整状态流转按下、移动、释放实现在 drag-handle-plugin.ts排查拖拽行为异常时可以从这个文件入手。锁定与解锁只读预览或审阅模式下可以用命令隐藏手柄editor.commands.lockDragHandle() // 隐藏并禁用 editor.commands.unlockDragHandle() // 恢复 editor.commands.toggleDragHandle() // 切换如果手柄完全不显示排查顺序是扩展是否真的在extensions数组里 → 容器是否留出左侧空间 → 是否被lockDragHandle或locked: true锁住了。拖拽排序跑通之后下一步值得看看 Node Range 扩展——它能选中多个块一起拖配合自定义节点视图拖拽体验可以做到更细粒度。【免费下载链接】tiptapThe headless rich text editor framework for web artisans.项目地址: https://gitcode.com/GitHub_Trending/ti/tiptap创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考