亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

react項(xiàng)目中使用react-dnd實(shí)現(xiàn)列表的拖拽排序功能

 更新時間:2023年02月06日 14:27:16   作者:songxueing  
這篇文章主要介紹了react項(xiàng)目中使用react-dnd實(shí)現(xiàn)列表的拖拽排序,本文結(jié)合實(shí)例代碼講解react-dnd是如何實(shí)現(xiàn),代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

現(xiàn)在有一個新需求就是需要對一個列表,實(shí)現(xiàn)拖拽排序的功能,要實(shí)現(xiàn)的效果如下圖:

可以通過 react-dnd 或者 react-beautiful-dnd 兩種方式實(shí)現(xiàn),今天先講下使用react-dnd是如何實(shí)現(xiàn)的,github地址:

https://react-dnd.github.io/react-dnd/docs/api/dnd-provider

1.先安裝依賴

npm i react-dnd

npm i react-dnd-html5-backend

2.創(chuàng)建一個 index.js 文件

DndProvider 組件為您的應(yīng)用程序提供 React-DnD 功能。這必須通過 backend 支柱注入后端,但也可以注入 window 物體。

  • backend:必填。一個React DnD后端。除非您正在編寫自定義的,否則您可能希望使用React DnD附帶的HTML5后端。
  • context: 可選的。用于配置后端的后端上下文。這取決于后端實(shí)現(xiàn)。
  • options: 可選的。用于配置后端的選項(xiàng)對象。這取決于后端實(shí)現(xiàn)。
import React from 'react'
import Example from './example'
import { DndProvider } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
	
class App extends React.Component{
    
    /**
    * 獲取排序后的新數(shù)據(jù)回調(diào)函數(shù)
    */
    handlePreviewList = (previewList) => {
        this.setState({
             previewList
        })
    }
	return (
		<div className="App">
			<DndProvider backend={HTML5Backend}>
				<Example previewList={previewList} 
                    handlePreviewList={this.handlePreviewList}/>
			</DndProvider>
		</div>
	)
}
	
export default App;

3.新建example.js文件

previewList是 index.js組件傳入的數(shù)據(jù)。

handlePreviewList 是保存排序后的新數(shù)據(jù)。

import React, { useState } from 'react'
import TopicList from './TopicList';
 
const Container = ({ previewList, handlePreviewList }) => {
    {
        const [topic] = useState(previewList)
        const handleDND = (dragIndex, hoverIndex) => {
            let tmp = previewList[dragIndex] //臨時儲存文件
            previewList.splice(dragIndex, 1) //移除拖拽項(xiàng)
            previewList.splice(hoverIndex, 0, tmp) //插入放置項(xiàng)
            handlePreviewList(previewList)
        };
        const renderCard = (item, index) => {
            return (
                <TopicList
                    key={item.questionTuid}
                    index={index}
                    id={item.questionTuid}
                    text={item.questionContent}
                    moveCard={handleDND}
                />
            )
        }
        return (
            <div>
                {
                    topic.map((item, i) => renderCard(item, i))
                }
            </div>
        )
    }
}
export default Container

4.新建TopicLis.js文件

useDrag 一個鉤子,用于將當(dāng)前組件用作拖動源。

參數(shù)

spec規(guī)范對象

返回值數(shù)組

  • Index 0:包含collect函數(shù)中收集的屬性的對象。如果collect未定義任何函數(shù),則返回空對象。
  • Index 1:拖動源的連接器功能。這必須附加到DOM的可拖動部分。
  • Index 2:拖動預(yù)覽的連接器功能。這可以附加到DOM的預(yù)覽部分。

規(guī)范對象成員

  • item:必填。一個簡單的JavaScript對象,描述被拖動的數(shù)據(jù)。這是關(guān)于拖動源的放置目標(biāo)可用的唯一信息,因此選擇他們需要知道的最小數(shù)據(jù)非常重要。你可能想在這里放一個復(fù)雜的引用,但是你應(yīng)該盡量避免這樣做,因?yàn)樗詈狭送蟿釉春头畔履繕?biāo)。返回類似于{ type, id }此方法的東西是個好主意。
  • item.type必須設(shè)置,它必須是字符串,ES6符號。只有為相同類型注冊的放置目標(biāo)才會對此項(xiàng)目做出反應(yīng)。閱讀概述以了解有關(guān)項(xiàng)目和類型的更多信息。
  • previewOptions: 可選的。描述拖動預(yù)覽選項(xiàng)的純JavaScript對象。
  • options: 可選的。一個普通的對象。如果組件的某些道具不是標(biāo)量(即,不是原始值或函數(shù)),則arePropsEqual(props, otherProps)options對象內(nèi)指定自定義函數(shù)可以提高性能。除非您遇到性能問題,否則不要擔(dān)心。
  • begin(monitor): 可選的。拖動操作開始時觸發(fā)。不需要返回任何內(nèi)容,但如果返回一個對象,它將覆蓋item規(guī)范的默認(rèn)屬性。
  • end(item, monitor): 可選的。當(dāng)拖動停止時,end被調(diào)用。對于每個begin呼叫,end保證相應(yīng)的呼叫。您可以調(diào)用monitor.didDrop()以檢查丟棄是否由兼容的放置目標(biāo)處理。如果它被處理,并且放置目標(biāo)通過從其方法返回普通對象來指定放置結(jié)果drop(),則它將可用作monitor.getDropResult()。此方法是觸發(fā)Flux動作的好地方。注意:如果在拖動時卸載組件,則component參數(shù)設(shè)置為null。
  • canDrag(monitor): 可選的。用它來指定當(dāng)前是否允許拖動。如果您想要始終允許它,只需省略此方法即可。如果您想基于某些謂詞禁用拖動,則指定它很方便props。注意:您可能無法調(diào)用monitor.canDrag()此方法。
  • isDragging(monitor): 可選的。默認(rèn)情況下,僅啟動拖動操作的拖動源被視為拖動。您可以通過定義自定義isDragging方法來覆蓋此行為。它可能會返回類似的東西props.id === monitor.getItem().id。如果在拖動過程中可以卸載原始組件并在以后使用其他父級“復(fù)活”,則執(zhí)行此操作。例如,當(dāng)在卡片板中的列表中移動卡時,您希望它保留拖動的外觀 - 即使在技術(shù)上,組件也會被卸載,并且每次將其移動到另一個列表時都會安裝另一個組件。注意:您可能無法調(diào)用monitor.isDragging()此方法。
  • collect: 可選的。收集功能。它應(yīng)該返回一個普通的道具對象返回注入你的組件。它接收兩個參數(shù),monitorprops。閱讀概述,了解監(jiān)視器和收集功能的介紹。請參閱下一節(jié)中詳細(xì)描述的收集功能。

useDrop 一個鉤子,用于將當(dāng)前組件用作放置目標(biāo)。

參數(shù)

spec規(guī)范對象

返回值數(shù)組

  • Index 0:包含collect函數(shù)中收集的屬性的對象。如果collect未定義任何函數(shù),則返回空對象。
  • Index 1:放置目標(biāo)的連接器功能。這必須附加到DOM的drop-target部分。

規(guī)范對象成員

  • accept:必填。一個字符串,一個ES6符號,一個數(shù)組或一個返回給定組件的函數(shù)的函數(shù)props。此放置目標(biāo)僅對指定類型的拖動源生成的項(xiàng)目作出反應(yīng)。
  • options: 可選的。一個普通的對象。如果組件的某些道具不是標(biāo)量(即,不是原始值或函數(shù)),則arePropsEqual(props, otherProps)options對象內(nèi)指定自定義函數(shù)可以提高性能。除非您遇到性能問題,否則不要擔(dān)心。
  • drop(item, monitor): 可選的。在目標(biāo)上放置兼容項(xiàng)目時調(diào)用。您可以返回undefined或普通對象。如果返回一個對象,它將成為放置結(jié)果,并且可以在其endDrag方法中作為拖動源使用monitor.getDropResult()。如果您希望根據(jù)接收到丟棄的目標(biāo)執(zhí)行不同的操作,這非常有用。如果您有嵌套的放置目標(biāo),則可以drop通過檢查monitor.didDrop()和測試是否已經(jīng)處理了嵌套目標(biāo)monitor.getDropResult()。此方法和源endDrag方法都是觸發(fā)Flux操作的好地方。如果canDrop()已定義并返回,則不會調(diào)用此方法false
  • hover(item, monitor): 可選的。當(dāng)項(xiàng)目懸停在組件上時調(diào)用。您可以檢查monitor.isOver({ shallow: true })以測試懸停是僅發(fā)生在當(dāng)前目標(biāo)上還是嵌套上。與drop()此不同,即使canDrop()定義并返回,也會調(diào)用此方法false。您可以檢查monitor.canDrop()以測試是否是這種情況。
  • canDrop(item, monitor): 可選的。使用它來指定放置目標(biāo)是否能夠接受該項(xiàng)目。如果您想要始終允許它,只需省略此方法即可。如果你想基于某個謂詞over props或者禁用刪除,那么指定它是很方便的monitor.getItem()。注意:您可能無法調(diào)用monitor.canDrop()此方法。
  • collect: 可選的。收集功能。它應(yīng)該返回一個普通的道具對象返回注入你的組件。它接收兩個參數(shù),monitorprops,了解監(jiān)視器和收集功能的介紹。請參閱下一節(jié)中詳細(xì)描述的收集功能。
import React, { useRef } from 'react'
import { useDrag, useDrop } from 'react-dnd'
import ItemTypes from './ItemTypes';
const style = {
  padding: '0.5rem 1rem',
  marginBottom: '.5rem',
  backgroundColor: 'white',
  cursor: 'move',
}
const TopicList = ({ id, text, index, moveCard }) => {
  const ref = useRef(null)
  const [, drop] = useDrop({
    //定義拖拽的類型
    accept: ItemTypes.TOPIC,    
    hover(item, monitor) {
      //異常處理判斷
      if (!ref.current) { 
        return
      }
      //拖拽目標(biāo)的Index
      const dragIndex = item.index;
      //放置目標(biāo)Index
      const hoverIndex = index; 
      // 如果拖拽目標(biāo)和放置目標(biāo)相同的話,停止執(zhí)行
      if (dragIndex === hoverIndex) { 
        return
      }
      //如果不做以下處理,則卡片移動到另一個卡片上就會進(jìn)行交換,下方處理使得卡片能夠在跨過中心線后進(jìn)行交換.
      //獲取卡片的邊框矩形
      const hoverBoundingRect = ref.current.getBoundingClientRect();    
      //獲取X軸中點(diǎn)
      const hoverMiddleY =
        (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2; 
      //獲取拖拽目標(biāo)偏移量
      const clientOffset = monitor.getClientOffset();   
      const hoverClientY = clientOffset.y - hoverBoundingRect.top
      // 從上往下放置
      if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {  
        return
      }
      // 從下往上放置
      if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {  
        return
      }
      moveCard(dragIndex, hoverIndex);  //調(diào)用方法完成交換
      item.index = hoverIndex;  //重新賦值index,否則會出現(xiàn)無限交換情況
    },
  })
  const [{ isDragging }, drag] = useDrag({
    item: { type: ItemTypes.TOPIC, id, index },
    collect: monitor => ({
      isDragging: monitor.isDragging(),
    }),
  })
  const opacity = isDragging ? 0 : 1
  drag(drop(ref))
  return (
    <div ref={ref} style={{ ...style, opacity }}>
      <span style={{ float: 'left' }}>{index + 1}.</span>
      <div className='stem' dangerouslySetInnerHTML={{ __html: text }}></div>
    </div>
  )
}
export default TopicList

5.新建 ItemTypes.js

export default {
  TOPIC: 'topic'
}

注意:react的版本需要是react16的新版本,否則會報如下圖所示的錯誤,具體兼容到幾,未測試,但是之前的react 16.4.2是實(shí)現(xiàn)不了當(dāng)前功能的,所以在開發(fā)前請確認(rèn)react版本

到此這篇關(guān)于react項(xiàng)目中使用react-dnd實(shí)現(xiàn)列表的拖拽排序的文章就介紹到這了,更多相關(guān)react-dnd列表的拖拽排序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React純前端模擬實(shí)現(xiàn)登錄鑒權(quán)

    React純前端模擬實(shí)現(xiàn)登錄鑒權(quán)

    這篇文章主要為大家詳細(xì)介紹了React純前端模擬實(shí)現(xiàn)登錄鑒權(quán)的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-04-04
  • React學(xué)習(xí)筆記之高階組件應(yīng)用

    React學(xué)習(xí)筆記之高階組件應(yīng)用

    這篇文章主要介紹了React 高階組件應(yīng)用,詳細(xì)的介紹了什么是React高階組件和具體使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • React?useEffect不支持async?function示例分析

    React?useEffect不支持async?function示例分析

    這篇文章主要為大家介紹了React?useEffect不支持async?function示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • React實(shí)現(xiàn)卡片拖拽效果流程詳解

    React實(shí)現(xiàn)卡片拖拽效果流程詳解

    這篇文章主要介紹了React Web開發(fā)實(shí)戰(zhàn)示例,實(shí)現(xiàn)卡片拖拽效果,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-11-11
  • React Native自定義標(biāo)題欄組件的實(shí)現(xiàn)方法

    React Native自定義標(biāo)題欄組件的實(shí)現(xiàn)方法

    今天講一下如何實(shí)現(xiàn)自定義標(biāo)題欄組件,我們都知道RN有一個優(yōu)點(diǎn)就是可以組件化,在需要使用該組件的地方直接引用并傳遞一些參數(shù)就可以了,這種方式確實(shí)提高了開發(fā)效率。對React Native自定義標(biāo)題欄組件的實(shí)現(xiàn)方法感興趣的朋友參考下
    2017-01-01
  • react koa rematch 如何打造一套服務(wù)端渲染架子

    react koa rematch 如何打造一套服務(wù)端渲染架子

    這篇文章主要介紹了react koa rematch 如何打造一套服務(wù)端渲染架子,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • react實(shí)現(xiàn)頁面水印效果的全過程

    react實(shí)現(xiàn)頁面水印效果的全過程

    大家常常關(guān)注的是網(wǎng)站圖片增加水印,而很少關(guān)注頁面水印,其實(shí)這個需求也是比較常見的,比如公文系統(tǒng)、合同系統(tǒng)等,這篇文章主要給大家介紹了關(guān)于react實(shí)現(xiàn)頁面水印效果的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • React路由組件三種傳參方式分析講解

    React路由組件三種傳參方式分析講解

    本文主要介紹了React組件通信之路由傳參(react-router-dom),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 一文詳解ReactNative狀態(tài)管理rematch使用

    一文詳解ReactNative狀態(tài)管理rematch使用

    這篇文章主要為大家介紹了ReactNative狀態(tài)管理rematch使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 基于React編寫一個全局Toast的示例代碼

    基于React編寫一個全局Toast的示例代碼

    前些日子在做項(xiàng)目的時候,需要封裝一個Toast組件,我想起之前用過的庫,只要在入口文件中引入就可以在全局中使用,還是很方便的,借這次機(jī)會也來實(shí)現(xiàn)一下,所以本文介紹了React中如何編寫一個全局Toast,需要的朋友可以參考下
    2024-05-05

最新評論