组件核心代码
// style.module.less
box-sizing: border-box;
min-width: 50px;
min-height: 50px;
z-index: 3;
import React, { ReactNode, useRef } from 'react';
import style from './style.module.less';
interface PropsType {
clasName?: string;
children: {
header: ReactNode;
main: ReactNode;
};
position?: string;
top?: number;
left?: number;
}
DragSlot.defaultProps = {
position: 'fixed',
top: 0,
left: 0,
}
export default function DragSlot(props: PropsType) {
const curRef = useRef(null);
const {position, top, left} = props;
const curPosition = position === 'fixed' ? 'fixed' : position === 'absolute' ? 'absolute' : 'fixed';
const curTop = typeof top === 'number' ? top : 0;
const curLeft = typeof left === 'number' ? left : 0;
const methods = {
handleMouseDown(e: React.MouseEvent) {
document.onselectstart = function() {return false;}
const currentRef: any = curRef.current;
const curWidth = currentRef.clientWidth;
const curHeight = currentRef.clientHeight;
e = e || window.event
var offsetX = e.clientX - currentRef.offsetLeft;
var offsetY = e.clientY - currentRef.offsetTop;
var screenWidth = document.body.offsetWidth - curWidth;
var screenHeight = document.body.offsetHeight - curHeight;
document.onmousemove = function (e) {
e = e || window.event;
var left = e.clientX - offsetX;
var top = e.clientY - offsetY;
currentRef.style.left = (left < 0 ? 0 : (screenWidth - left < 0 ? screenWidth : left)) + "px";
currentRef.style.top = (top < 0 ? 0 : (screenHeight - top < 0 ? screenHeight : top)) + "px";
}
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
document.onselectstart = null;
if (currentRef.releaseCapture) {
currentRef.releaseCapture();
}
}
return false;
}
}
return (<div className={`${props.clasName} ${style.root}`}
style={{position: `${curPosition}`, top: `${curTop}`, left: `${curLeft}`}}
ref={curRef}>
<div onMouseDown={(event) => {methods.handleMouseDown(event)}}>
{props.children.header}
</div>
<div>
{props.children.main}
</div>
</div>)
};
组件使用
import DragSlot from '@/views/Components/DragSlot';
<DragSlot >{{
header: (<>
我是自定义头部
</>),
main: (<>
我是主要内容
</>)
}}</DragSlot>