如何为WP自定义Gutenberg区块实现拖拽排序功能?
给Gutenberg自定义区块实现拖拽排序的可行方案
要实现你要的拖拽排序效果,直接用WordPress官方@wordpress/components里的Sortable组件就够了——这是官方维护的组件,完全适配Gutenberg生态,比那些过时的第三方库靠谱得多,不会出现编译失败的问题。
具体实现步骤:
1. 引入所需组件
先在区块代码里导入Sortable和SortableItem:
import { Sortable, SortableItem } from '@wordpress/components';
2. 修改Edit组件的排序逻辑
把原来的普通列表替换成Sortable组件,每个列表项用SortableItem包裹,通过onSortEnd回调更新区块的items属性:
edit: (props) => { const blockProps = useBlockProps(); const { attributes: { items }, setAttributes } = props; // 处理排序完成后的逻辑 const handleSortEnd = ({ oldIndex, newIndex }) => { const newItems = [...items]; // 调整数组元素位置 const [movedItem] = newItems.splice(oldIndex, 1); newItems.splice(newIndex, 0, movedItem); // 更新区块属性 setAttributes({ items: newItems }); }; return ( <div {...blockProps}> <Sortable onSortEnd={handleSortEnd}> {items.map((item, index) => ( <SortableItem key={`${item}-${index}`} index={index}> <div className="item">{item}</div> </SortableItem> ))} </Sortable> </div> ); },
3. 优化拖拽样式(可选)
在style.scss里加一点样式,提升拖拽体验:
.item { padding: 0.5rem 0.75rem; margin: 0.25rem 0; background: #f0f0f1; border-radius: 4px; cursor: grab; &:active { cursor: grabbing; } }
完整代码示例
整合后的完整区块代码:
import { registerBlockType } from "@wordpress/blocks"; import "./style.scss"; import metadata from "./block.json"; import { useBlockProps } from "@wordpress/block-editor"; import { Sortable, SortableItem } from '@wordpress/components'; registerBlockType(metadata.name, { attributes: { items: { type: "array", default: ["carrot", "cabbage", "zucchini"], }, }, edit: (props) => { const blockProps = useBlockProps(); const { attributes: { items }, setAttributes } = props; const handleSortEnd = ({ oldIndex, newIndex }) => { const newItems = [...items]; const [movedItem] = newItems.splice(oldIndex, 1); newItems.splice(newIndex, 0, movedItem); setAttributes({ items: newItems }); }; return ( <div {...blockProps}> <Sortable onSortEnd={handleSortEnd}> {items.map((item, index) => ( <SortableItem key={`${item}-${index}`} index={index}> <div className="item">{item}</div> </SortableItem> ))} </Sortable> </div> ); }, save: (props) => { const blockProps = useBlockProps.save(); const { attributes: { items } } = props; return ( <div {...blockProps}> {items.map((item) => ( <div className="item">{item}</div> ))} </div> ); }, });
方案优势
- 官方维护,和Gutenberg版本同步,不会出现API兼容问题
- 内置拖拽动画和无障碍支持,无需自己实现复杂逻辑
- 用法简洁,和React生态完全适配
内容的提问来源于stack exchange,提问作者ostaladafab
相关产品推荐
相关产品推荐

