Skip to content

复盘时间

整理时间

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>
  );
}