在做项目的时候,碰到这样的一个问题,那就是model框需要做成如下样式:
那是不是直接去改样式就行了呢
改了一些样式,但是也遇到很多问题,全屏是css样式去调整,那么我把拖拽,全屏代码放到下边:
1.封装model框
import {useState, useRef, useEffect, useCallback} from "react";
import { Modal, ModalProps } from "antd";
import Draggable from "react-draggable";
import styles from "./desModel.less";
import {CloseOutlined} from "@ant-design/icons";
import {useWatch} from "antd/es/form/Form";
import provider from "react-redux/src/components/Provider";
//ModalProps 继承官方modal属性,使用时属性提示
interface WebModal extends ModalProps {
openDrag?: boolean; //是否开启弹窗的拖拽
dragHandle?: boolean; //开启头部拖拽或者弹窗拖拽
}
const WebReactModal= ({
openDrag = false,
dragHandle = false,
...props
}: WebModal) => {
const [position,setPosition]=useState({ x: 0, y: 0 })
const [bounds, setBounds] = useState({
left: 0,
top: 0,
bottom: 0,
right: 0,
}); //存储模态框的边界值
const [ji , setJi]=useState("");
const draggleRef = useRef<any>();
//模态框开始移动计算莫太框的位置和边界
const onStart = (event, uiData) => {
const { clientWidth, clientHeight } = window?.document?.documentElement;
//获取到模态框的位置,从而计算可以动的边界值
const targetRect = draggleRef?.current?.getBoundingClientRect();
setBounds({
left: -targetRect?.left + uiData.x,
right: clientWidth - (targetRect?.right - uiData.x),
top: -targetRect?.top + uiData.y,
bottom: clientHeight - (targetRect?.bottom - uiData.y),
});
};
//因为设置了初始位置,所以添加模态框移动时更新位置
const onDrag = (e, data) => {
const { x, y } = data;
setPosition({ x, y });
};
//监听模态框的关闭,恢复到初始的位置
useEffect(() => {
if (!props.open) {
setPosition({ x: 0, y: 0 });
}
//这里监听我的状态,不管拖拽到哪,我点击全屏时,回归原位
if(props?.flagModels === true){
setPosition({ x: 0, y: 0 });
}
}, [props?.open , props?.flagModels]);
return (
<Modal
maskClosable={false}
closeIcon={<CloseOutlined style={{ color : '#fff' }} />}
className={styles.webModal}
modalRender={(modal) => (
<Draggable
handle={dragHandle?"":'.ant-modal-header'}
disabled={openDrag}
onDrag={onDrag}
bounds={bounds}
position={position}
onStart={(event, uiData) => onStart(event, uiData)}
>
<div ref={draggleRef}>{modal}</div>
</Draggable>
)}
{...props}
>
{props?.children}
</Modal>
);
};
export default WebReactModal;
2. 对应封装的model框样式
//index.less 样式文件
.webModal {
:global {
.ant-modal-content {
.ant-modal-header {
padding: 10px;
height: 55px;
background: #269421;
border-bottom: 1px solid #269421;
border-radius: 0 0 0 0;
}
}
//标题样式,可根据自己需要修改样式
.ant-modal-title {
color: #fff;
width: 97%;
font-size: 20px;
cursor: move;
user-select: none;
font-weight: bold;
}
}
}
3.父组件
<WebModal width={flagModel ? '100%' : 1200} style={{
margin: flagModel ? '0' : '0 auto',
maxWidth: flagModel ? '100%' : '100vw-32px',
position : 'relative',
top : flagModel ? '0' : '100px',
height : flagModel ? '100%' : '200px',
}}
onOk={onFinishModel}
title={
<div style={{ display : 'flex', justifyContent: 'space-between' , cursor : flagModel ? 'auto' : 'move' }}>
<span>{modelTitle}</span>
<span className={'kpps'} style={{ cursor : 'pointer' , fontSize : 16 , marginTop : 2 }} onClick={() => {
setFlagModel(!flagModel)
console.log(flagModel)
}}>
<FullscreenOutlined style={{ color : "#fff" , display : flagModel ? 'none' : 'block' }} />
<FullscreenExitOutlined style={{ color : "#fff", display : flagModel ? 'block' : 'none' }} />
</span>
</div>
}
open={isModalOpen}
onCancel={handleCancel}
flagModels={flagModel}
>
<div className={flagModel ? 'mlp' : ''} style={{ padding : 20 }}>
这是内容
</div>
</WebModal>
4.父组件的样式,因为我试了试,一些样式写在子组件的less里没有生效
.kpps{
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
}
.kpps:hover {
inset-inline-end: 12px;
z-index: 1010;
padding: 0;
color: rgba(0, 0, 0, 0.45);
font-weight: 600;
line-height: 1;
text-decoration: none;
background-color: rgba(0,0,0,0.1);
border-radius: 4px;
width: 32px;
height: 32px;
border: 0;
outline: 0;
transition: color 0.2s,background-color 0.2s;
}
.ant-modal .ant-modal-header {
color: rgba(0, 0, 0, 0.88);
background: #ffffff;
margin-bottom: 8px;
padding: 0;
border-bottom: none;
}
.ant-modal .ant-modal-footer {
text-align: end;
background: transparent;
margin-top: 12px;
margin-right: 20px;
padding: 0;
border-top: none;
border-radius: 0;
}
.mlp{
height: calc(100vh - 55px - 72px)
}
父组件的样式比较粗糙,还是需要再深究下
那么这个框就好了,可以根据自己的需要去制作需要的样式,希望能提供帮助,欢迎评论