1.如何拖拽
- 接收到这个需求的时候,一想拖拽,简单用用react-resizable插件应该解决了,然后我发现是我了解需求太浅了!antd-pro 哪里有有入口给我去包装组建,发现 menuRender可以重写,我简单尝试了一下,发现工作量不小!!!有没有可以让使用者不需要改造代码的方法?
答案是有的。 我想到了原生js,直接创建节点不就行行了吗?说搞就搞,贴上代码
import { useEffect, useState } from "react";
interface DragSiderProps {
initWidth?: number;
parentClass?: string;
initStyle?: string;
}
const useSiderDragWidth = ({
initWidth = 220,
parentClass = ".ant-layout-sider",
initStyle = `
position: absolute; width: 2px;
height: 100%;
right: 0;
cursor: col-resize;
z-index: 112;
top: 0;`,
}: DragSiderProps) => {
const [width, setWidth] = useState(initWidth);
useEffect(() => {
if (document.querySelector(parentClass)) {
let node = document.createElement("div");
node.setAttribute(
"style",
`
${initStyle}
`
);
node.onmousedown = function (e: MouseEvent) {
e.preventDefault();
document.onmousemove = mouseMove;
document.onmouseup = mouseUp;
};
document.querySelector(parentClass)?.appendChild(node);
}
let event = null;
function mouseMove(e: MouseEvent) {
event = e || window.event;
setWidth(event.clientX);
}
//终止事件
function mouseUp() {
document.onmousemove = null;
document.onmouseup = null;
}
}, []);
return { width };
};
export { useSiderDragWidth };
很简单的思路逻辑,重新操作了一把原生方法,也就50行代码,使用方只需要引用这个hook方法
const { width } = useSiderDragWidth ({});
<ProLayout
route={defaultProps}
location={{
pathname,
}}
navTheme="light"
fixSiderbar
siderWidth={width} //在这个地方使用
headerRender={false}
menuItemRender={(item: any, dom: any) => (
<a
onClick={() => {
navigate(item.path || "/dashboard");
}}
>
{dom}
</a>
)}
>
{page}
</ProLayout>
使用者需要记住 initWidth parentClass initStyle 配合使用就行了,默认支持antd-pro 左右菜单