이 글의 내용은 React DND에서 구현한 카드 정렬 기능(코드 예제)에 대한 내용입니다. 필요한 친구들이 참고할 수 있기를 바랍니다.
저는 회사에서 처음으로 React를 사용하고 있습니다. 요구 사항 중 하나가 드래그 앤 드롭 정렬 기능을 구현하도록 요청한 후 구현 방법을 기록하고 antd 및 ReactDND를 사용하여 이 기능을 구현하겠습니다.
먼저 create-react-app
스캐폴딩을 사용하여 기본 React 프로젝트를 생성합니다. create-react-app
脚手架创建一个最基本的react项目。
npm install -g create-react-app create-react-app my-app cd my-app
OK,构建好了react项目,然后我们引入antd
,和react-dnd
$ yarn add antd $ yarn add react-dnd $ yarn add react-dnd-html5-backend
引用完antd后可以按照antd官网上的方法完成按需加载。
我们先使用antd写出一个简单的卡片列表,修改项目目录的APP.js和App.css文件,新建一个文件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
好了,卡片编写完成了,现在运行一下我们的项目,看一下效果
$ npm start or yarn start
OK,编写完成,我们现在要做的就是使用react-dnd
完成卡片的拖拽排序,使得firstCard,secondCard,thirdCard可以随意的交换。
react-dnd中提供了DragDropContext,DragSource,DropTarget 3种API;
DragDropContext 用于包装拖拽根组件,DragSource
和 DropTarget
都需要包裹在DragDropContex
内
DropTarget 用于包装你需要拖动的组件,使组件能够被拖拽
DragSource 用于包装接收拖拽元素的组件,使组件能够放置
理解了这些API的作用,一个卡片排序的构建思路大体就浮现出来了,怎么样实现一个卡片排序,其实很简单,就是把卡片列表中的每一个卡片都设置为DropTarget
和DragSource
,最后在拖拽结束的时候进行卡片之间的重排序,完成这一功能的实现。下面我们就来一步一步的实现它。
首先设定DragDropContext
,在App.js
中引入 react-dnd
和react-dnd-html5-backend
(先npm install
//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);OK, React 프로젝트가 빌드되고
antd
및 react-dnd
를 소개합니다
//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)antd를 인용한 후 antd 공식에 있는 방법을 따르시면 됩니다. 누르는 작업을 완료하려면 웹사이트를 로드해야 합니다.
2. 기능 구현
먼저 antd를 사용하여 간단한 카드 목록을 작성하고, 프로젝트 디렉토리에 있는 APP.js 및 App.css 파일을 수정한 후, CardItem.js
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);
//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,否则会出现无限交换情况 } }
자, 작성이 완료되었습니다. 이제 해야 할 일은 react-dnd
를 사용하여 드래그 앤 드롭 정렬을 완료하는 것입니다. 카드를 사용하므로 firstCard, secondCard, thirdCard를 마음대로 교환할 수 있습니다. react-dnd는 DragDropContext, DragSource 및 DropTarget의 3가지 API를 제공합니다.
DragSource
와 DropTarget
은 모두 DragDropContex
DragSource는 드래그 요소를 받는 컴포넌트를 래핑하여 컴포넌트를 배치할 수 있도록 하는 데 사용됩니다.
이러한 API의 기능을 이해하고 나면 카드 정렬을 구성하는 일반적인 아이디어가 떠오릅니다. 카드 정렬을 구현하는 방법은 실제로 매우 간단합니다. 카드 목록을 DropTarget
및 DragSource
에 추가하고 마지막으로 드래그가 끝나면 카드 순서를 변경하여 이 기능 구현을 완료합니다. 단계별로 구현해 보겠습니다. 먼저 DragDropContext
를 설정하고 react-dnd
및 react-dnd-html5-backend
를 App.js
에 도입하세요. > code>(npm install
이 플러그인을 먼저 설치하세요)
//App.js handleDND = (dragIndex,hoverIndex) => { let CardList = this.state.CardList; let tmp = CardList[dragIndex] //临时储存文件 CardList.splice(dragIndex,1) //移除拖拽项 CardList.splice(hoverIndex,0,tmp) //插入放置项 this.setState({ CardList }) }; /* ... */ //添加传递参数传递函数 <carditem></carditem>자, 이제 App.js로 래핑된 하위 구성 요소는 DropTarget 및 DragSource를 사용할 수 있습니다. 이제 하위 구성 요소인 CardItem에 반응을 설정합니다. -dnd를 사용하면 이제 카드에 끌기 효과가 있습니다.
rrreee
마지막 연결 방법은 ReactDND 공식 홈페이지에 있는 안내를 참고하시면 됩니다. lodash.flow 공식 홈페이지에 가시면 보실 수 있고 다운로드도 가능합니다. 🎜물론 @DragSource(type, spec,collect) 및 @DropTarget(types, spec,collect)와 같은 참조용 생성자 메서드를 선택할 수도 있습니다.🎜🎜데코레이터를 사용할 계획이 없더라도 부분 _.flow와 같은 기능적 구성🎜도우미를 사용하여 JavaScript에서 여러 DragSource 및🎜DropTarget 선언을 결합할 수 있기 때문에 애플리케이션은 여전히 유용할 수 있습니다. 데코레이터를 사용하면 동일한 효과를 얻기 위해🎜데코레이터를 쌓기만 하면 됩니다.🎜rrreee🎜 이제 드래그 효과 구현을 완료했습니다. 이제 드래그 효과를 살펴보겠습니다. 다음으로 드래그 앤 드롭 후 정렬 기능을 완료해야 합니다. 🎜App.js에 정렬 기능을 넣고 CardItem.js의 CardTarget 생성자에 있는 호버 기능에서 이를 호출합니다. 구체적인 구현 방법을 살펴보겠습니다.🎜rrreeerrreee🎜자, 이제 카드가 완성되었습니다. 정렬 기능, 효과를 살펴보자! 🎜🎜🎜🎜🎜🎜🎜🎜위 내용은 React DND로 구현한 카드 정렬 기능(코드 예시)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!