国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

react 基于 dnd-kit 封裝的拖拽排序組件

這篇具有很好參考價(jià)值的文章主要介紹了react 基于 dnd-kit 封裝的拖拽排序組件。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

dnd-kit使用方法

  • 官網(wǎng)地址 https://docs.dndkit.com/introduction/installation

  • 安裝依賴

npm install @dnd-kit/core
npm install @dnd-kit/sortable
  • 簡(jiǎn)單使用

建議直接看官網(wǎng),已經(jīng)描述得很詳細(xì)了:https://docs.dndkit.com/presets/sortable文章來源地址http://www.zghlxwxcb.cn/news/detail-598712.html

封裝成組件使用

效果展示
dnd-kit,component,react.js,javascript,前端
type dataType = {
  id: string
  title: string
}
export default () => {
  const [list, setList] = useState<dataType[]>([])
  useEffect(() => {
    getData()
  }, [])

  const getData = async () => {
    setTimeout(() => {
      const data = new Array(10).fill('標(biāo)題-').map((s,i) => (
        {id: 'id-' + i, title: s + i}
      ))
      setList(data)
    }, 200);
  }

  const onDragEnd = (list: dataType[], ids: string[]) => {
    setList(list)
  }

  return (
    <div >
      <SortListDndKit list={list} onDragEnd={onDragEnd}>
        {list.map((item) => (
          <SortItemDndKit key={item.id} id={item.id}>
            <div>
              <h4>{item.title}</h4>
            </div>
          </SortItemDndKit>
        ))}
      </SortListDndKit>
    </div>
  )
}
注意事項(xiàng)
  1. 如果傳入的是一個(gè)函數(shù)式組件,需要用一個(gè)html元素包裹住
<SortListDndKit list={list} onDragEnd={onDragEnd}>
{list.map((item) => (
  <SortItemDndKit>
    {/* 這里需要用html元素包裹一下 */}
    <div>
      <Text title='測(cè)試組件' />
    </div>
  </SortItemDndKit> 
))}
</SortListDndKit>
  1. 這里的排序默認(rèn)是讀取 list 中的 id 作為 key 值的,如果 key 值是其他,可以指定 list 中傳入的 idKey
{/* newId:list中的id名稱 */}
<SortListDndKit idKey="newId" list={list} onDragEnd={onDragEnd}></SortListDndKit>
  1. 如果內(nèi)部的元素綁定了鼠標(biāo)點(diǎn)擊之類的事件,需要先阻止事件冒泡 onMouseDown={e => e.stopPropagation()}
<SortListDndKit list={list} onDragEnd={onDragEnd}>
{list.map((item) => (
  <SortItemDndKit>
    {/* 這里需要用html元素包裹一下 */}
    <div>
      <h4>這里有很多內(nèi)容</h4>
      {/* 這里需要阻止鼠標(biāo)點(diǎn)擊事件的冒泡 */}
      <button onMouseDown={e => e.stopPropagation()} onClick={()=>console.log('點(diǎn)擊了')} >點(diǎn)擊</button>
    </div>
  </SortItemDndKit> 
))}
</SortListDndKit>
組件源碼
import React, { ReactNode } from 'react';
import {
  DndContext,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  DragEndEvent,
  MouseSensor,
} from '@dnd-kit/core';
import {
  arrayMove,
  SortableContext,
  sortableKeyboardCoordinates,
  useSortable,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';

type PropsType = {
  /** 需要傳遞的列表 */
  list: any[];
  /** list的key值,默認(rèn)是id */
  idKey?: string;
  children: ReactNode;
  /** 拖拽結(jié)束的回調(diào) */
  onDragEnd: (arr: any[], ids: string[]) => void;
};

/** 參考官網(wǎng):https://docs.dndkit.com/presets/sortable */
/** 
 * 列表排序
 */
export const SortListDndKit = ({
  list = [],
  idKey = 'id',
  children,
  onDragEnd,
}: PropsType) => {
  // 指定傳感器,默認(rèn)是全部
  const sensors = useSensors(
    // useSensor(PointerSensor),
    useSensor(MouseSensor),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    }),
  );
  // 拖拽結(jié)束
  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event;
    if (active.id !== over.id) {
      const oldIndex = list.findIndex((item) => item[idKey] === active.id);
      const newIndex = list.findIndex((item) => item[idKey] === over.id);
      const ids: string[] = list.map((item) => item[idKey]);
      [ids[newIndex], ids[oldIndex]] = [ids[oldIndex], ids[newIndex]];
      const _val = arrayMove(list, oldIndex, newIndex);
      onDragEnd(_val, ids);
    }
  };

  return (
    <DndContext
      sensors={sensors}
      collisionDetection={closestCenter}
      onDragEnd={handleDragEnd}
    >
      <SortableContext items={list.map((item) => item[idKey])}>
        {children}
      </SortableContext>
    </DndContext>
  );
};

type SortItemType = {
  id: string;
  children: ReactNode;
};

/**
 * 列表排序的子項(xiàng)
 * - 函數(shù)式組件作為children,需要用html元素包裹住
 * - 例:
 * - \<SortItemDndKit>
 * -   \<div>\<Text title='測(cè)試組件' />\</div>
 * - \</SortItemDndKit> 
 */
export const SortItemDndKit = ({ id, children }: SortItemType) => {
  const { attributes, listeners, setNodeRef, transform, transition } =
    useSortable({ id });
  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
  };
  const newChild = React.Children.map(children, (child) => {
    if (!React.isValidElement(child)) {
      return null;
    }
    const childProps = {
      ...child.props,
      ref: setNodeRef,
      style,
      ...attributes,
      ...listeners,
    };
    return React.cloneElement(child, childProps);
  });
  return <>{newChild}</>;
};

到了這里,關(guān)于react 基于 dnd-kit 封裝的拖拽排序組件的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包