IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> react-封装拖拽组件 -> 正文阅读

[JavaScript知识库]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

完工。

?

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-08 07:59:00  更:2022-05-08 07:59:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:06:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码