React Antd4.x Upload实现图片上传后拖拽换顺序功能

12 篇文章 0 订阅

功能说明

做项目使用React Antd4.x Upload上传图片,实现批量上传。

后期项目迭代更新,要求拖拽图片调整图片顺序。

框架不支持,自己借助包写了一个上传且可以拖拽图片换位置的功能。

下面是思路具体步骤:

1、框架Upload实现批量上传,预览,删除。

2、Upload旁边增加拖拽换位置的按钮。

3、点击按钮弹窗,弹窗中实现拖拽。

设计原因:上传与拖拽互不影响。

功能实现

安装“array-move”

$ npm i array-move

安装“react-sortable-hoc"

$ npm install react-sortable-hoc --save

封装拖拽弹窗组件

/* eslint-disable react-hooks/exhaustive-deps */
import React, { useEffect, useState, } from "react";
import { Modal, } from 'antd';
import { SortableContainer, SortableElement, } from 'react-sortable-hoc';
import { arrayMoveImmutable } from 'array-move';
import './style.less';
import CTSTooltip from '@/components/CTSTooltip';

const handlePreview = (value,) => {
  if (value) {
    const image = new Image();
    image.src = value;
    const imageWindow = window.open(value);
    imageWindow.document.write(image.outerHTML);
  }
}

const handleOver = (value) => {
  document.getElementById(`img-operate-wrap${value}`).style.display = 'block';
}

const handleOut = (value) => {
  document.getElementById(`img-operate-wrap${value}`).style.display = 'none';
}

const SortableItem = SortableElement(({ value, onDelete }) => <div onMouseOut={() => handleOut(value)} onMouseOver={() => handleOver(value)} className='img-box-wrap'>
  <img alt='' className='img-box' src={value}></img>
  <div className='img-operate-default' id={`img-operate-wrap${value}`}>
    <div className='img-icon-wrap'>
      <CTSTooltip title="预览" iconName="icon-yulan" onTooltipIcon={() => handlePreview(value)} />
      <CTSTooltip className="del" title="删除" iconName="icon-lajitong" onTooltipIcon={() => onDelete(value)} />
    </div>
  </div>
</div>
);

const SortableList = SortableContainer(({ items, onDelete }) => {
  return <div style={{ display: 'flex', flexWrap: 'wrap' }}>{
    items && items.map((value, index) => (
      <SortableItem key={`item-${value.url}`} index={index} onDelete={onDelete} value={value.url} />
    ))}
  </div>
});

const CTSChangePosition = ({
  visible,
  fileListAll,
  onConfirm,
  onCancel,
  loading = false,
}) => {
  const [fileTempList, setFileTempList] = useState(fileListAll);

  useEffect(() => {
    setFileTempList(fileListAll);
  }, []);

  const handleOk = () => {
    // console.log("final ----", fileTempList);
    onConfirm(fileTempList);
  }

  const onSortEnd = ({ oldIndex, newIndex }) => {
    let finalList = arrayMoveImmutable(fileTempList, oldIndex, newIndex);
    setFileTempList(finalList);
  };

  const handleDelete = (value) => {
    // console.log("value - value", value, fileTempList);
    if (value) {
      let dealFileList = fileTempList.filter(item => item.url !== value);
      // console.log("dealFileList", dealFileList,);
      setFileTempList(dealFileList);
    }
  }

  return (<Modal width="70%" loading={loading} title={'拖拽调整图片顺序'} onOk={handleOk} maskClosable={false} onCancel={onCancel} visible={visible} >
    <SortableList distance={10} axis="xy" items={fileTempList} onSortEnd={onSortEnd} onDelete={(value) => handleDelete(value)} />
  </Modal>)
}

export default CTSChangePosition;
.img-box-wrap {
  position: relative;
  z-index: 9999;

  .img-box {
    width: 104px;
    height: 104px;
    margin-right: 8px;
    margin-bottom: 8px;
    border: 1px dashed #d9d9d9;
    background: white;
  }

  .img-operate-default {
    width: 104px;
    height: 104px;
    margin-right: 8px;
    margin-bottom: 8px;
    display: none;
    position: absolute;
    top: 0;
    left: 0;
    opacity: 0.5;
    background-color: black;

    .iconfont {
      color: white;
      font-size: 20px;
    }

    .icon-lajitong {
      margin-left: 6px;
    }

    .icon-yulan {
      margin-right: 6px;
    }

    .img-icon-wrap {
      width: 104px;
      height: 104px;
      display: flex;
      justify-content: center;
      align-items: center;
      color: white;
    }
  }

}

组件的引用:

 <Button className='btn' onClick={() => handleChangeImagePosition()}>调整图片顺序</Button>
 
{visible && <CTSChangePosition visible={visible} fileListAll={fileListAll} onConfirm={(fileListDeal) => handleModalConfirm(fileListDeal)} onCancel={() => handleModalClose()} />}
  const handleChangeImagePosition = () => {
    setVisible(true);
  }

  const handleModalClose = () => {
    setVisible(false);
  }

  const handleModalConfirm = (fileListDeal) => {
    setFileListAll(fileListDeal);
    if (form) {
      form.setFieldsValue({
        [`${name[0]}`]: {
          [name[1]]: fileListDeal
        }
      })
    }
    handleModalClose();
  }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值