Der Inhalt dieses Artikels befasst sich mit der von React DND implementierten Kartensortierfunktion. Ich hoffe, dass er für Sie hilfreich ist.
Als ich React im Unternehmen zum ersten Mal lernte, wurde ich in einer der Anforderungen aufgefordert, die Drag-and-Drop-Sortierfunktion zu implementieren. Nach Abschluss werde ich die Implementierungsmethode aufzeichnen und antd und ReactDND verwenden, um diese Funktion zu implementieren.
Verwenden Sie zunächst create-react-app
Gerüst, um ein grundlegendes Reaktionsprojekt zu erstellen.
npm install -g create-react-app create-react-app my-app cd my-app
OK, das Reaktionsprojekt wird erstellt, und dann stellen wir antd
vor, und react-dnd
$ yarn add antd $ yarn add react-dnd $ yarn add react-dnd-html5-backend
Nach dem Zitieren von antd können Sie das Laden bei Bedarf gemäß der Methode abschließen auf der offiziellen Website von andd.
Wir verwenden zunächst antd, um eine einfache Kartenliste zu schreiben, ändern die Dateien APP.js und App.css im Projektverzeichnis und erstellen eine neue Datei CardItem.js
//App.js import React, { Component } from 'react'; import CardItem from './CardItem' import './App.css'; const CardList = [{ //定义卡片内容 title:"first Card", id:1, content:"this is first Card" },{ title:"second Card", id:2, content:"this is second Card" },{ title:"Third Card", id:3, content:"this is Third Card" } ]; class App extends Component { state = { CardList }; render() { return ( <div> {CardList.map((item,index) => { return( <carditem></carditem> ) })} </div> ); } } export default App; //App.css .card{ display: flex; margin: 50px; } .card div{ margin-right: 20px; } //CardItem.js import React, { Component } from 'react'; import {Card} from 'antd' class CardItem extends Component{ render(){ return( <div> <card> <p>{this.props.content}</p> </card> </div> ) } } export default CardItem
Okay, das Schreiben der Karte ist abgeschlossen, jetzt führen Sie unser Projekt aus und sehen den Effekt
$ npm start or yarn start
OK, das Schreiben ist abgeschlossen, wir Jetzt müssen Sie mit react-dnd
die Drag-and-Drop-Sortierung der Karten abschließen, sodass firstCard, secondCard und ThirdCard nach Belieben ausgetauscht werden können.
react-dnd bietet 3 APIs: DragDropContext, DragSource und DropTarget;
DragDropContext wird verwendet, um die Drag-Root-Komponente zu umschließen, DragSource
und DropTarget
beide müssen in DragDropContex
DropTarget eingeschlossen werden, um die Komponente einzuschließen, die Sie ziehen müssen, damit die Komponente gezogen werden kann
DragSource wird verwendet, um die Komponente zu umschließen, die das Drag-Element empfängt, sodass die Komponente platziert werden kann
Verstehen Die Rolle dieser APIs besteht darin, jede Karte in der Kartenliste auf DropTarget
und DragSource
zu setzen Schließlich, wenn das Ziehen abgeschlossen ist, ordnen Sie die Karten neu an, um die Implementierung dieser Funktion abzuschließen. Lassen Sie es uns Schritt für Schritt umsetzen.
Zuerst einrichten DragDropContext
, App.js
und react-dnd
in react-dnd-html5-backend
einführen (zuerst npm install
dieses Plug-in)
//App.js import React, { Component } from 'react'; import CardItem from './CardItem' + import {DragDropContext} from 'react-dnd' + import HTML5Backend from 'react-dnd-html5-backend' import './App.css'; /*.. ..*/ - export default App; + export default DragDropContext(HTML5Backend)(App);
Nun, es wird jetzt von der App verwendet .js Die umschlossenen Unterkomponenten können jetzt DropTarget und DragSource verwenden. Wir haben jetzt in der Unterkomponente CardItem React-DND festgelegt, sodass die Karte nun einen Drag-Effekt haben kann.
//CardItem.js import React, { Component } from 'react'; import {Card} from 'antd' + import { //引入react-dnd DragSource, DropTarget, } from 'react-dnd' const Types = { // 设定类型,只有DragSource和DropTarget的类型相同时,才能完成拖拽和放置 CARD: 'CARD' }; //DragSource相关设定 const CardSource = { //设定DragSource的拖拽事件方法 beginDrag(props,monitor,component){ //拖拽开始时触发的事件,必须,返回props相关对象 return { index:props.index } }, endDrag(props, monitor, component){ //拖拽结束时的事件,可选 }, canDrag(props, monitor){ //是否可以拖拽的事件。可选 }, isDragging(props, monitor){ // 拖拽时触发的事件,可选 } }; function collect(connect,monitor) { //通过这个函数可以通过this.props获取这个函数所返回的所有属性 return{ connectDragSource:connect.dragSource(), isDragging:monitor.isDragging() } } //DropTarget相关设定 const CardTarget = { drop(props, monitor, component){ //组件放下时触发的事件 //... }, canDrop(props,monitor){ //组件可以被放置时触发的事件,可选 //... }, hover(props,monitor,component){ //组件在target上方时触发的事件,可选 //... }, }; function collect1(connect,monitor) {//同DragSource的collect函数 return{ connectDropTarget:connect.dropTarget(), isOver:monitor.isOver(), //source是否在Target上方 isOverCurrent: monitor.isOver({ shallow: true }), canDrop: monitor.canDrop(),//能否被放置 itemType: monitor.getItemType(),//获取拖拽组件type } } class CardItem extends Component{ render(){ const { isDragging, connectDragSource, connectDropTarget} = this.props; let opacity = isDragging ? 0.1 : 1; //当被拖拽时呈现透明效果 return connectDragSource( //使用DragSource 和 DropTarget connectDropTarget( <div> <card> <p>{this.props.content}</p> </card> </div> ) ) } } // 使组件连接DragSource和DropTarget let flow = require('lodash.flow'); export default flow( DragSource(Types.CARD,CardSource,collect), DropTarget(Types.CARD,CardTarget,collect1) )(CardItem)
Für die letzte Verbindungsmethode verweise ich auf die Anweisungen auf der offiziellen ReactDND-Website. Sie können sie auf der offiziellen Website von lodash.flow anzeigen und herunterladen.
Natürlich können Sie auch die Konstruktormethode als Referenz auswählen, z. B. @DragSource(type, spec, Collect) und @DropTarget(types, spec, Collect).
Auch wenn Sie nicht planen Um Dekoratoren zu verwenden, kann die Teilanwendung immer noch praktisch sein, da Sie mehrere DragSource- und DropTarget-Deklarationen in JavaScript mithilfe eines funktionalen Kompositionshilfsprogramms wie _.flow kombinieren können. Mit Dekoratoren können Sie einfach stapeln die
Dekoratoren, um den gleichen Effekt zu erzielen.
import { DragSource, DropTarget } from 'react-dnd'; import flow from 'lodash/flow'; class YourComponent { render() { const { connectDragSource, connectDropTarget } = this.props return connectDragSource(connectDropTarget( /* ... */ )) } } export default flow( DragSource(/* ... */), DropTarget(/* ... */) )(YourComponent);
Sie können den Effekt des Ziehens deutlich erkennen. Als nächstes müssen wir die Sortierfunktion nach dem Ziehen und Platzieren abschließen. Wir fügen die Sortierfunktion in App.js ein und rufen sie in der Hover-Funktion im CardTarget-Konstruktor in CardItem.js auf. Als nächstes schauen wir uns die spezifische Implementierungsmethode an.
//CardItem.js const CardTarget = { hover(props,monitor,component){ if(!component) return null; //异常处理判断 const dragIndex = monitor.getItem().index;//拖拽目标的Index const hoverIndex = props.index; //放置目标Index if(dragIndex === hoverIndex) return null;// 如果拖拽目标和放置目标相同的话,停止执行 //如果不做以下处理,则卡片移动到另一个卡片上就会进行交换,下方处理使得卡片能够在跨过中心线后进行交换. const hoverBoundingRect = (findDOMNode(component)).getBoundingClientRect();//获取卡片的边框矩形 const hoverMiddleX = (hoverBoundingRect.right - hoverBoundingRect.left) / 2;//获取X轴中点 const clientOffset = monitor.getClientOffset();//获取拖拽目标偏移量 const hoverClientX = (clientOffset).x - hoverBoundingRect.left; if (dragIndex hoverIndex && hoverClientX > hoverMiddleX) { // 从后往前放置 return null } props.DND(dragIndex,hoverIndex); //调用App.js中方法完成交换 monitor.getItem().index = hoverIndex; //重新赋值index,否则会出现无限交换情况 } }
Okay, jetzt haben wir es Ich habe eine kleine Demo der Kartensortierfunktion fertiggestellt. Schauen wir uns den Effekt an!
Das obige ist der detaillierte Inhalt vonVon React DND implementierte Kartensortierfunktion (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!