react-封装拖拽组件

环境:"react": "^16.8.6",

           "react-sortable-hoc": "^2.0.0"

因项目中需要实现拖拽列,其他地方也需要使用所以单独封装成一个组件,方便其他地方调用。

先看成品:

功能是拖拽列前面ico图标可以上下替换

1、封装sortable组件

import React from "react";
import {
  sortableContainer,
  sortableElement,
  sortableHandle,
} from "react-sortable-hoc"; // 拖拽的关键组件
import styled from "@emotion/styled"; // 设置局部css

const ListItem = styled.div`
  display: flex;
  min-height: 50px;
  align-items: center;
  background-color: #f5f5f5;
  border-radius: 4px;
  margin-bottom: 10px;
  padding-left: 8px;
  padding-right: 15px;
  box-sizing: border-box;
  z-index: 9999;
`;
const DrapIcon = styled.span`
  padding-right: 8px;
  cursor: move;
`;
const ChildCom = styled.div`
  flex: 1;
`;
const DeleteBtn = styled.div`
  color: #999;
  font-size: 16px;
  cursor: pointer;
`;

// 拖拽时原列表替换
function arrayMoveMutable(array, fromIndex, toIndex) {
	const startIndex = fromIndex < 0 ? array.length + fromIndex : fromIndex;

	if (startIndex >= 0 && startIndex < array.length) {
		const endIndex = toIndex < 0 ? array.length + toIndex : toIndex;

		const [item] = array.splice(fromIndex, 1);
		array.splice(endIndex, 0, item);
	}
}

// 拖拽时返回新数组
function arrayMoveImmutable(array, fromIndex, toIndex) {
	array = [...array];
	arrayMoveMutable(array, fromIndex, toIndex);
	return array;
}

// 拖拽容器
const SortableContainer = sortableContainer(({ children }) => {
  return <div>{children}</div>;
});

// 拖拽ico
const DragHandle = sortableHandle(() => (
  <DrapIcon className="iconfont icon-tuozhuai"></DrapIcon>
));

function Sortable(props) {
  const { dataSource=[], ComSortItem, sortEnd } = props;
  function handleDelete(index) {
    const List = [...dataSource];
    List.splice(index,1)
    sortEnd(List);
  }
  // 数据更新
  function updateData(val,index) {
    const List = [...dataSource];
    List[index] = val;
    sortEnd(List);
  }
  // 拖拽体
  const SortableItem = sortableElement(({ value,sortIndex }) => {
    return (
      <ListItem>
        <DragHandle />
        <ChildCom>
          <ComSortItem data={value} index={sortIndex} updateData={updateData} />
        </ChildCom>
      </ListItem>
    );
  });

  // 拖拽后回调
  const onSortEnd = ({ oldIndex, newIndex }) => {
    const List = arrayMoveImmutable(dataSource, oldIndex, newIndex);
    sortEnd(List);
  };
  return (
    <>
      <SortableContainer onSortEnd={onSortEnd} useDragHandle>
        {dataSource.length > 0 &&
          dataSource.map((value, index) => (
            <SortableItem
              key={`sortable-item-${index}`}
              index={index}
              value={value}
              sortIndex={index}
            />
          ))}
      </SortableContainer>
    </>
  );
}

export default Sortable;

2、调用sortable组件

import React from 'react'
import { Checkbox } from 'antd'

import Sortable from 'component/Sortable'
import AddForm from './add'
import styled from '@emotion/styled'

const ItemBox = styled.div`
  display: flex;
  justify-content: space-between;
  .name{
    width: 100%;
    overflow: hidden; //超出的文本隐藏
  text-overflow: ellipsis; //溢出用省略号显示
  white-space: nowrap; //溢出不换行
  }
`
const Opt = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
`
const RightBox = styled.div`
  width: 250px;
  border: 1px solid #ddd;
  display: flex;
  flex-direction: column;
  border: 1px solid #d9d9d9;
  border-radius: 2px;
  .item-con {
    padding: 10px;
  }
`

// 自定义拖拽体
function AddForm(props) {
  const { data, updateData, index } = props
  const { attributeName, checked } = data
  const changeChecked = (e) => {
    const isChecked = e.target.checked
    updateData({ ...data, checked: isChecked}, index)
  }
  return (
    <ItemBox>
      <div className='name'>{attributeName}</div><Opt>
        <Checkbox onChange={changeChecked} checked={checked} ></Checkbox>
      </Opt>
    </ItemBox>
    )
}

const Right = (props) => {
  // dataSource 数据列表 setRightList拖拽后回调函数
  const { dataSource, setRightList } = props

  const updateSource = (val) => {
    setRightList(val)
  }

  return (
    <RightBox>
      <div className='item-con' style={{ height: '400px', overflow: 'auto' }}>
        <Sortable
          className='sortable'
          dataSource={dataSource}
          ComSortItem={(p) => <AddForm {...p} />}
          sortEnd={(val) => {
            updateSource(val)
          }}
        />
      </div>
    </RightBox>
  )
}

export default Right

完工。

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值