复盘时间
整理时间
2023-10-8
2023-10-9
封装风格
描述 页面模态框
INFO
对于一个页面可能你会存在多个模态框,但是同一时间你只可能打开一个模态框。
所以页面中只能由一个组件Modal
,然后使用类型来进行判断,到底是哪一个Modal
思路
上图所示,页面中总共会有三种模态框
- 新增和编辑
- 查看
- 查看审批流
这时候我们不能简单地用三个状态来表示模态框的开闭,或者说,使用了三个模态框,这样对于每一种Modal
都需要有一个开闭状态的话,就会导致大量的代码重复
我们可以使用type
来判断当前打开的到底是哪一个模态框
示例
改变前
javascript
const QRCodeApply: React.FC = () => {
const formsRef = useRef<FormInstance>();// 表单实例
const [isAddOpen, setIsAddOpen] = useState(false);// 控制增加模态框
const [isViewOpen, setIsViewOpen] = useState(false);// 控制查看模态框
const [isViewProcessOpen, setIsViewProcessOpen] = useState(false);// 控制查看审批流程模态框
const [isEdit, setIsEdit] = useState(false);// 是否是编辑状态
// 是否打开模态框
const isModalOpen = useMemo(() => {
return isAddOpen || isViewOpen || isViewProcessOpen;
}, [isAddOpen || isViewOpen || isViewProcessOpen]);
// 模态框标题
const modalTitle = useMemo(() => {
if (isAddOpen) {
if (isEdit) {
return "二维码申请-新增";
} else {
return "二维码申请-编辑";
}
} else if (isViewOpen) {
return "二维码申请-查看";
} else if (isViewProcessOpen) {
return "二维码申请-查看审批流程";
}
return "";
}, [isAddOpen, isViewOpen, isViewProcessOpen, isEdit]);
// 关闭模态框
function onModalsClose() {
if (isAddOpen) {
onModalCancel(setIsAddOpen, formsRef);
} else if (isViewOpen) {
onModalCancel(setIsViewOpen, formsRef);
} else if (isViewProcessOpen) {
onModalCancel(setIsViewProcessOpen, formsRef);
} else {
return;
}
};
// 打开模态框, type: 1:新增,2:查看,3:查看审批流程
function onModalsOpen(record: any, type: number) {
switch (type) {
case 1:
onModalOpen(formsRef, setIsAddOpen, record, setIsEdit);
break;
case 2:
onModalOpen(formsRef, setIsViewOpen, record);
break;
case 3:
onModalOpen(formsRef, setIsViewProcessOpen, record);
break;
default:
break;
}
};
// 确定事件
function onModalOk() {
console.log("onModalOk");
}
const setAlertMessage = (
<div>
<div>1. 申请编号请输入台账或项目编号等有明确含义的内容。</div>
<div>2. 填写无误后可以直接发起审批流程,OA审批通过后将生成二维表格!</div>
<div>3. 二维码与枪是否一致,默认否,如果需要生成的子码和二维码一样,则选择是</div>
</div>
);
// 删除记录
const onDelete = (record: any) => {
console.log("onDelete", record);
};
const modalContent = () => {
if (isAddOpen) {
return (
// 增加模态框内容
)
} else if (isViewOpen) {
return (
// 查看模态框内容
)
} else if (isViewProcessOpen) {
return (
// 查看审批流内容
)
} else
{
return <></>;
}
};
return (
<div>
<ProTableWithJumpPage
columns={QRCodeApplicationTableColumns({ onOpen: onModalsOpen, onDelete, setIsEdit })}
setOpen={() => onModalsOpen({}, 1)}
needBatch={false}
request={mockQRCodeApplicationRequest}
/>
<ShowModal
title={modalTitle}
open={isModalOpen}
onOk={onModalOk}
onCancel={onModalsClose}
>
{modalContent()}
</ShowModal>
</div>
);
};
export default QRCodeApply;
改变后
javascript
const QRCodeApply: React.FC = () => {
const formsRef = useRef<FormInstance>();// 表单实例
const [modalType, setModalType] = useState(1);// 控制模态框类型 1:新增,2:查看,3:查看审批流程
const [modalOpen, setModalOpen] = useState(false);// 控制模态框是否打开
const [isEdit, setIsEdit] = useState(true);// 是否是编辑状态
const isModalOpen = useMemo(() => {
return modalOpen;
}, [modalType, modalOpen]);
// 模态框标题
const modalTitle = useMemo(() => {
switch (modalType) {
case 1:
return isEdit ? "二维码申请编辑" : "二维码申请新增";
case 2:
return "二维码申请查看";
case 3:
return "二维码申请审批流程";
default:
return "";
}
}, [modalType, isEdit]);
// 关闭模态框
function onModalsClose() {
onModalCancel(setModalOpen, formsRef);
};
// 打开模态框, type: 1:新增,2:查看,3:查看审批流程
function onModalsOpen(record: any, type: number) {
onModalOpen(formsRef, setModalOpen, record, setIsEdit, setModalType, type);
};
// 确定事件
function onModalOk() {
console.log("onModalOk");
}
const setAlertMessage = (
<div>
<div>1. 申请编号请输入台账或项目编号等有明确含义的内容。</div>
<div>2. 填写无误后可以直接发起审批流程,OA审批通过后将生成二维表格!</div>
<div>3. 二维码与枪是否一致,默认否,如果需要生成的子码和二维码一样,则选择是</div>
</div>
);
// 删除记录
const onDelete = (record: any) => {
console.log("onDelete", record);
};
// ProForm表单内容
function modalFormTextItem(arr: { label: string, name: string; }[]) {
return arr.map((item) => {
return <ProFormText
label={item.label}
name={item.name}
width={"md"}
required
key={item.name}
/>;
});
}
// 模态框内容-新增
function modalContentAdd() {
return (
// 新增模态框
);
}
// 模态框内容-查看
function modalContentView() {
return (
// 查看模态框
);
}
// 模态框内容-查看审批流程
function modalContentViewProcess() {
return (
// 查看审批模态框
);
}
// 模态框内容
const modalContent = () => {
switch (modalType) {
case 1:
return modalContentAdd();
case 2:
return modalContentView();
case 3:
return modalContentViewProcess();
default:
return <></>;
}
};
return (
<div>
<ProTableWithJumpPage
columns={QRCodeApplicationTableColumns({ onOpen: onModalsOpen, onDelete, setIsEdit })}
setOpen={() => onModalsOpen({}, 1)}
needBatch={false}
request={mockQRCodeApplicationRequest}
/>
<ShowModal
title={modalTitle}
open={isModalOpen}
onOk={onModalOk}
onCancel={onModalsClose}
>
{modalContent()}
</ShowModal>
</div>
);
};
export default QRCodeApply;
补充
根据模态款的内容发现,我们会使用到很多的ProFormText
,如果每个都写,那么又会增加很多重复的代码,这时候我们最好将ProFormText
封装起来,用循环
去遍历生成ProFormText
,然后再将他们插入到代码中
javascript
// ProForm表单内容
function modalFormTextItem(arr: { label: string, name: string; }[]) {
return arr.map((item) => {
return <ProFormText
label={item.label}
name={item.name}
width={"md"}
required
key={item.name}
/>;
});
}
// 模态框内容-新增
function modalContentAdd() {
return (
<HorizontalProForm formRef={formsRef}>
<ProFormSelect
label="客户项目"
name={"customerProject"}
width={"md"}
required
/>
{modalFormTextItem([
{ label: "申请编号", name: "applicationNumber" },
{ label: "申请项目", name: "applicationProject" },
{ label: "申请数量", name: "applicationQuantity" },
{ label: "枪数", name: "gunNumber" },
])}
<ProFormSelect
label="二维码与枪数是否一致"
name={"isConsistent"}
options={[
{ label: '是', value: '1' },
{ label: '否', value: '0' },
]}
width={"md"}
required
/>
<ProFormTextArea
label="备注"
name={"remarks"}
width={"md"}
/>
</HorizontalProForm>
);
}