首先看效果:
1、首先就是主要代码 index.tsx
import { FC, useEffect, useRef, useState } from "react";
import columns, { columnsType } from "./config";
import { Input } from "antd";
import "./style.less";
//是不是拖拽情况
let isMouseWidth: boolean = false;
//相同class的集合
let classNameArr: any[] = [];
const Table: FC = () => {
const [list, setList] = useState<any[]>([]);
let realDom: HTMLElement | null | any;
let line: any = document.getElementById("line");
useEffect(() => {
let arr = new Array();
for (let i = 0; i < 50; i++) {
let obj = {};
for (let j = 0; j < 10; j++) {
obj = { ...obj, [`title${j}`]: `${i}-${j}` };
}
arr = [...arr, obj];
}
setList(arr);
}, []);
//鼠标移动
window.onmousemove = (e) => {
if (!isMouseWidth) {
return;
}
try {
line.style.display = "block ";
line.style.left = `${e.clientX}px `;
} catch (e) {}
};
//鼠标抬起
window.onmouseup = (e) => {
if (isMouseWidth == false) {
return;
}
try {
//保留最少10px的宽度
if (e.clientX - realDom.offsetLeft < 10) {
return;
}
line.style.display = "none";
realDom.style.width = `${e.clientX - realDom.offsetLeft}px `;
classNameArr.forEach((ele, index) => {
ele.style.width = `${e.clientX - realDom.offsetLeft}px `;
});
//鼠标准备移动时,全局文字不可选中
document.onselectstart = function () {
return true;
};
} catch (e) {}
isMouseWidth = false;
};
//返回相同class的元素
const getElementsByClassName = (className: any) => {
let d = document;
let children = d.getElementsByTagName("*") || document.all; //获取页面所有元素
let elements = new Array(); //定义一个数组,用于存储所得到的元素
//获取元素的class为className的所有元素
for (let i = 0; i < children.length; i++) {
let child = children[i];
let classNames = child.className.split(" ");
for (let j = 0; j < classNames.length; j++) {
if (classNames[j] == className) {
elements.push(child); //如果class存在,则存入elements
break;
}
}
}
return elements;
};
//一个整体的表
const getList = () => {
return (
<>
{list.map((ele, index) => {
return (
<div className="list" key={index}>
{getItem(ele, index)}
</div>
);
})}
</>
);
};
//一条数据
const getItem = (itemObj: any, indexObj: number) => {
let Arr: any[] = [];
for (let ele in itemObj) {
columns().forEach((element: columnsType, index: number) => {
if (element.dataIndex == ele) {
Arr = [
...Arr,
{
text: itemObj[ele],
valueType: element.valueType,
key: element.key,
},
];
return;
}
});
}
return (
<>
{Arr.map((ele: any, index: number) => {
return <>{getBox(ele, indexObj)}</>;
})}
</>
);
};
//一个格子
const getBox = (ele: any, indexObj: number) => {
//input 输入的值处理
const handleInputOnChange = (e: any) => {
list[indexObj][ele.key] = e.target.value;
let copy = JSON.parse(JSON.stringify(list));
setList(copy);
};
//input 输入的值处理
const handleSelectOnChange = (e: any) => {
list[indexObj][ele.key] = e.target.value;
let copy = JSON.parse(JSON.stringify(list));
setList(copy);
};
return (
<>
{ele.key != "title4" ? (
<input
className={`${ele.key} input`}
value={ele.text}
onChange={handleInputOnChange}
/>
) : (
<select
className={`${ele.key} select`}
value={ele.text}
onChange={handleSelectOnChange}
>
<option>123</option>
<option>124</option>
<option>125</option>
</select>
)}
</>
);
};
return (
<>
<div className="table">
<div className="header" key="header">
{columns().map((ele, index) => {
return (
<>
<div className="title" id={ele.key}>
{ele.title}{" "}
<div
className="mouseWidth"
onMouseDown={(e) => {
console.log("鼠标按下");
isMouseWidth = true;
classNameArr = getElementsByClassName(ele.key);
realDom = document.getElementById(ele.key);
//鼠标准备移动时,全局文字不可选中
document.onselectstart = function () {
return false;
};
}}
onMouseUp={(e) => {
console.log("鼠标已经移除");
isMouseWidth = false;
}}
></div>
</div>
</>
);
})}
</div>
{getList()}
<div className="line" id="line"></div>
</div>
</>
);
};
export default Table;
2、配置文件 config.ts
const columns = () => {
let arr: columnsType[] = [
{
title: 'title0',
dataIndex: 'title0',
key: 'title0',
}, {
title: 'title1',
dataIndex: 'title1',
key: 'title1',
}, {
title: 'title2',
dataIndex: 'title2',
key: 'title2',
}, {
title: 'title3',
dataIndex: 'title3',
key: 'title3',
}, {
title: 'title4',
dataIndex: 'title4',
key: 'title4',
}, {
title: 'title5',
dataIndex: 'title5',
key: 'title5',
}, {
title: 'title6',
dataIndex: 'title6',
key: 'title6',
}, {
title: 'title7',
dataIndex: 'title7',
key: 'title7',
}, {
title: 'title8',
dataIndex: 'title8',
key: 'title8',
}, {
title: 'title9',
dataIndex: 'title9',
key: 'title9',
},
]
return arr
}
export type columnsType = {
title: string,
dataIndex: string,
key: string,
hideInTable?: boolean,
hideSearch?: boolean,
valueType?: string
}
export default columns
3、最后补上样式 style.less
.header {
display: flex;
position: relative;
height: 25px;
.title {
width: 100px;
border: 1px solid #ccc;
position: relative;
overflow: hidden;
}
}
.list {
display: flex;
.item {
.box {}
}
}
.select {
width: 100px;
height: 20px;
border: 1px solid #ccc;
}
.input {
width: 100px;
border: 1px solid #ccc;
height: 20px;
text-align: center;
overflow: hidden;
}
.mouseWidth {
position: absolute;
// border: solid 1px red;
// background-color: #ccc;
width: 10px;
height: 23px;
top: 0px;
right: -5px;
cursor: col-resize
}
.line{
position: absolute;
left: 50px;
top: 0px;
height: 100%;
z-index: 2;
width: 1px;
background-color: blue;
display: none;
}
.table{
// overflow: scroll;
// width: 150%;
// height: 60%;
// position: absolute;
}