【拖拽排序插件】dnd-kit

插件选择

react常用的拖拽排序插件,一般会推荐这几个:react-beautiful-dnd、react-dnd、dnd-kit、react-sortable-hoc,怎么选择呢react-beautiful-dnd插件可以去git上看看作者说不再维护了,并且npm仓库里面也是没有的,你去下载会报错,就不用了,react-dnd插件比较大,实现复杂的拖拽场景,就暂时不用它,剩下两个随便挑一个把,就以dnd-kit为例子。

1.安装

我们需要安装下面几个相关插件:@dnd-kit/core、@dnd-kit/sortable、@dnd-kit/utilities

他们一次的功能在于拖动,排序,以及样式,下面我们从代码中可以看出来。

pnpm install @dnd-kit/core

2.使用场景和代码

一个简单的场景,一组div的列,可以拖动排序,下面是写成的组件代码:

1)组件代码

import { injectIntl } from "react-intl";
import { DndContext, closestCenter } from '@dnd-kit/core';
import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable';
import { useState } from "react";
import { CSS } from '@dnd-kit/utilities';
import './my-dnd.less'

interface props_type {
    items: any,
    onDragEnd: any,
    renderItem: any,
    prefix: any,
    className: string
}

const DraggableRow = ({ id, render, item, prefix, className, activeId }: any) => {
    const { attributes, listeners, transform, setNodeRef, transition } = useSortable({ id });
    const isDragging = id === activeId;

    const style = {
      transform: CSS.Transform.toString(transform),
      transition,
      background: isDragging ? 'linear-gradient(rgba(0, 140, 214, 0.1), rgba(0, 110, 255, 0.1)), #ffffff' : ''
    };
  
    return (
      <div ref={setNodeRef} style={style} className={`${className} dnd-item`}>
        <div {...attributes} {...listeners} className="drag-icon">
          {prefix}
        </div>
        {render(item)}
      </div>
    );
};


const MyDnd: React.FC<any> = (props: props_type) => {
    const { items, onDragEnd, renderItem, prefix, className } = props;
    const [currentItems, setCurrentItems] = useState(items);
    const [activeId, setActiveId] = useState(null);

  const handleDragEnd = (event: any) => {
    const { active, over } = event;

    if (active.id !== over.id) {
      const oldIndex = currentItems.findIndex((item: any) => item.id === active.id);
      const newIndex = currentItems.findIndex((item: any) => item.id === over.id);

      const newItems = arrayMove(currentItems, oldIndex, newIndex);
      setCurrentItems(newItems);
      onDragEnd && onDragEnd(newItems);
    }
    setActiveId(null);
  };

  return (
    <DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd} onDragStart={(e: any) => setActiveId(e.active.id)}>
      <SortableContext items={currentItems.map((item: any) => item.id)} strategy={verticalListSortingStrategy}>
        {currentItems.map((item: any) => (
          <DraggableRow
            key={item.id}
            id={item.id}
            item={item}
            render={renderItem}
            prefix={prefix}
            className={className}
            activeId={activeId}
          />
        ))}
      </SortableContext>
    </DndContext>
  );
}

export default injectIntl(MyDnd) as any;

 

2)如何使用

import MyDnd from "./my-dnd";

<MyDnd
 items={list} 
 onDragEnd={(newItems: any) => set_list(newItems)}
 renderItem={renderRow}
 prefix={icon}
 className={'file-item'}
/>

3.代码分析

1)MyDnd传参

        先从使用的地方看,items是需要传入到SortableContext中进行排序的源数据,onDragEnd是触发完成排序后的回调函数,返回的是新的数据,renderItem是你自己定义的页面的样式每一行的,perfix是自定义每一行前面的icon,这里我是穿了个按钮进去,并把拖拽的动作挂载(listeners,随后会介绍)在这个按钮上的。

2)MyDnd代码

然后就进入组件的代码:DndContext :将整个应用包裹在DndContext 中,并设置 collisionDetectionclosestCenter(检测最近的元素碰撞),SortableContextSortableContext 包裹所有可排序项,设置 strategyverticalListSortingStrategy(垂直列表的排序策略)。中间就是你要加载的自己的内容啦,就是renderItemuseSortable 提供了处理单个元素拖拽的基本接口。

3)样式

@dnd-kit/utilities主要提供了拖动时触发的样式效果。

大概就是这样,具体的API可以再具体查询。

### Vue3 拖拽插件推荐 对于 Vue3 的拖拽功能实现,`vuedraggable` 是一个常用的解决方案。然而,在 Vue3 中使用 `vuedraggable` 需要注意其版本兼容性问题。以下是关于如何正确选择和配置适用于 Vue3 的拖拽插件的相关说明。 #### vuedraggable@next 版本支持 Vue3 为了适配 Vue3,官方推出了 `vuedraggable@next` 版本[^2]。此版本基于 Composition API 构建,并解决了与 Vue3 不兼容的问题。安装该插件时需指定版本号: ```bash npm install vuedraggable@next ``` 在项目中引入并注册组件的方式如下所示: ```javascript import { defineComponent } from 'vue'; import draggable from 'vuedraggable'; export default defineComponent({ components: { draggable, }, }); ``` 通过上述方式可以成功集成到 Vue3 项目中。 #### 使用 vue-dnd-kit 替代方案 如果遇到 `vuedraggable` 在特定场景下的局限性或者希望尝试其他更灵活的选择,则可考虑采用 **vue-dnd-kit**。这是一个专门为现代前端框架设计的拖放库,具有高度自定义能力以及良好的性能表现。它不仅限于列表项之间的交换操作,还能够处理复杂的多区域交互逻辑。 安装命令如下: ```bash npm install @dnd-kit/core @dnd-kit/utilities @dnd-kit/sortable ``` 下面是一个简单的例子展示如何利用 `vue-dnd-kit` 创建基本的排序列表功能: ```html <template> <div class="container"> <SortableContext items="{items}"> <ul> <li v-for="(item, index) in sortableItems" :key="index"> {{ item }} </li> </ul> </SortableContext> </div> </template> <script setup lang="ts"> import { ref } from 'vue'; import { SortableContext, useSortable, } from '@dnd-kit/vue-sortable'; import { arrayMove } from '@dnd-kit/sortable'; const initialItems = ['Item 1', 'Item 2', 'Item 3']; const items = ref(initialItems); function handleSortEnd({ activeIndex, overIndex }) { const newItems = arrayMove(items.value, activeIndex, overIndex); items.value = newItems; } </script> ``` 以上代码片段展示了如何借助 `vue-dnd-kit` 实现基础的拖拽效果[^3]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值