美文网首页
图标的拖动排序

图标的拖动排序

作者: 楠楠_c811 | 来源:发表于2018-12-14 18:03 被阅读16次

    最近遇到一个新的需求,要求弹窗展示一个图标列表,然后每个图标都可以拖动排序......
    what?
    拖动排序?然后满脑子就是碰撞、判断、上下左右......
    为什么一个小图标要做的这么复杂?能看不就好了么?
    ......当然,如果你打不过产品经理,还说不过他,你还能做什么呢????
    乖乖去找方法解决喽,还能咋地?
    当然了,我一直认为技术不能逾越市场,也不能让技术引领产品潮流。因为毕竟术业有专攻,在产品设计这件事情上,听产品的不是错。
    这块代码是一个的react的子组件,最后会被作为组件调用。

    // 我是一个独立封装的子组件
    import React from 'react'
    // 定义当前要拖拽的图标
    let curDragIndex = null;
    
    // 封装子组件
    export default function dragSort(props){
      // 定义所有需要拖拽的图标
      let container = props.children;
      // from 是要拖拽的列,to是行,封装变化事件函数
      function onChange(from, to){
        // 如果是同一个,说明没有执行拖拽,直接返回
        if(from === to ) return ;
        // 定义当前被拖拽的数据
        let curValue = props.data;
        // 定义执行后当前最新的数组
        let newValue = arrMove(curValue, from, to);
        // 判断传进来的参数是否有 onChange 方法,如果有就执行父级的onChange
        if(typeof props.onChange === 'function'){
          // 如果调用父级的onChange函数方法,就根据传参返回最新的数组
          return props.onChange(newValue, from ,to);
        }
      }
      return (
        <div>
          {/* 循环遍历表格的每一项*/}
          {container.map((item, index)=>{
            // 判断是不是react组件。用来增加代码的健壮性,防止渲染的时候出错
            if(React.isValidElement(item)){
              // 如果是,克隆并返回一个新的 ReactElement (内部子元素也会跟着克隆),
              // 新返回的元素会保留有旧元素的 props、ref、key,也会集成新的 props(只要在第二个参数中有定义)
              return React.cloneElement(item, {
                // 设置元素可拖动
                draggable:"true",
                // 开始拖拽
                onDragStart: function(){
                  // 获取被拖拽的数据的起始位置下标
                  curDragIndex = index
                },
                // 拖拽过程中
                onDragEnter: function() {
                  // 执行onChange函数,获取最新位置,达到互换效果
                  onChange(curDragIndex, index)
                  // 当前拖拽的数据顶替之前这个位置的数据
                  curDragIndex = index;
                },
                // 拖拽停止
                onDragEnd: function(){
                  curDragIndex = null;
                  // 判断如果这里有调用函数事件
                  if(typeof props.onDragEnd === 'function'){
                    // 就让他调用停止事件
                    props.onDragEnd()
                  }
                }
              })
            }
            // 将最终的item return 出去
            return item;
          })}
        </div>
        )
    }
    // 设置函数,接收参数
    function arrMove(arr, fromIndex, toIndex){
      // 合并原有数组赋值给一个新数组
      arr = [].concat(arr);
      // 取到传进来的起始位置的值  item是需要插入的内容
      let item = arr.splice(fromIndex, 1)[0];
      // 将插入的内容加到目的点的后面,返回一个新的数组
      arr.splice(toIndex , 0, item);
      return arr;
    }
    
    

    封装好这个组件之后,剩下的就是传参调用了。我这个拖拽排序是写在一个弹框里的,实现效果是打开弹框,获取到数据,然后拖拽操作。

    // 记得要在最上面引入封装的组件文件哦
    
    class Currency extends Component{
    //拖动排序事件
      handleTableChange = (pagination, filters, sorter) => {
        this.setState({newSort: sorter.order, newSortField: sorter.field}, () =>
          this._getTokenList(pagination.current - 1, pagination.pageSize, this.state.newSort, this.state.newSortField, this.state.searchInput, this.state.searchBlack, this.state.searchAble, this.state.searchAsset));
      };
    
      handleDragMove = (data, from, to) => {
        this.setState({
          curMoveItem: to,
          tokenList: data
        })
      };
    
      handleDragEnd = () => {
        this.setState({
          curMoveItem: null
        })
      };
      render(){
        return(
          <div>
            // 弹框
            <Modal
                title="我是antd的弹框组件"
                visible={this.state.sort}
                onOk={this.handleOk}
                onCancel={this.handleCancel}
            >
                 <p>上下拖动可调整展示排序</p>
                // 我是上面封装的组件哦
                 <DragSort onDragEnd={this.handleDragEnd} 
                            onChange={this.handleDragMove} 
                            data={this.state.tokenList}>
                    {
                        this.state.tokenList.map((token,index)=>{
                           return (
                                <ul>
                                  <li>
                                    <div key={index}>
                                      <span>{token.id}</span>
                                      <img style={{width: 50, height: 50, margin:10 }} src={token.icon} />
                                      <span>{token.symbol}</span>
                                    </div>
                                  </li>
                                </ul>
                              )
                            })
                          }
                  </DragSort>
              </Modal>
          </div>
        )
      }
    }
    
    

    相关文章

      网友评论

          本文标题:图标的拖动排序

          本文链接:https://www.haomeiwen.com/subject/wfjghqtx.html