前言

接触React + Ant Design开发也有一段时间了,也已经慢慢习惯了React + Ant Design。最近开发的需求功能里,需要一个全屏弹窗的功能,类似于ElementUI里的Dialog组件fullscreen属性设置为true的效果。然而发现Ant DesignModal组件并不支持全屏效果。
Github上翻了一下其他开发者提的issue,发现2018年的时候有其他开发者已经提了:https://github.com/ant-design/ant-design/issues/12359
在这里插入图片描述
Antd开发者afc163对于此需求则回复:

建议自行封装吧,暂时不会增加这样的功能。
如果内容比较多,也可以尝试 Drawer。

看来只能自己动手丰衣足食了。

方案1:通过参数实现

Modal组件提供了比较丰富的参数,其中有两个参数,分别是bodyStylestyle以及width。其中bodyStyle参数控制Modal组件的body部分样式,style参数则用于设置浮层的样式,调整浮层位置等,width参数控制宽度。

方案1思路

所谓全屏,说简单一点,就是弹窗的宽度和高度分别等于浏览器可视区域的宽度和高度。
对于宽度,我们尝试通过设置参数width="100vw"来控制弹窗的宽度:

     <Modal
        title="Basic Modal"
        width="100vw"
        visible={isModalVisible}
        onOk={handleOk}
        onCancel={handleCancel}
      >
      ...
      </Modal>

然后发现通过上述方式改变宽度之后,弹窗的左右及上下区域,分别出现了空白:
在这里插入图片描述
对于左右两边区域的空白,我们通过F12查看网页源代码,可以发现是Modal组件divmax-width样式导致:max-width: calc(100vw - 32px);
在这里插入图片描述
针对于这个问题,我们只要通过Modal组件的style参数来修改max-width样式,将其设置为100vw即可:

     <Modal
        style={{
          maxWidth: "100vw"
        }}
        title="Basic Modal"
        width="100vw"
        visible={isModalVisible}
        onOk={handleOk}
        onCancel={handleCancel}
      >
      ...
      </Modal>

而对于弹窗的高度,我们通过设置参数style={{maxWidth: "100vw", height: "100vh"}},将高度设置为100vh,发现并没有什么用,看来我们只能另辟蹊径了。
对于弹窗上边区域的空白,我们可以通过设置top: 0的方式来消除:style={{maxWidth: "100vw", top: 0}},其中top: 0表示Modal组件div元素,距离顶部设置为0。
另外,弹窗的高度,我们可以设置Modal组件body区域的高度,将其设置为100vh - 弹窗header部分高度 - 弹窗footer部分高度即可,其中header部分和footer部分的高度分别为55和52:
在这里插入图片描述
代码:

     <Modal
        style={{
          maxWidth: "100vw",
          top: 0
        }}
        bodyStyle={{
          height: "calc(100vh - 55px - 53px)"
        }}
        title="Basic Modal"
        width="100vw"
        visible={isModalVisible}
        onOk={handleOk}
        onCancel={handleCancel}
      >
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
      </Modal>

然而问题又来了,弹窗底部出现了空白:
在这里插入图片描述
对此,我们需要额外的将padding-bottom设置为0:

     <Modal
        style={{
          maxWidth: "100vw",
          top: 0,
          paddingBottom: 0
        }}
        bodyStyle={{
          height: "calc(100vh - 55px - 53px)"
        }}
        title="Basic Modal"
        width="100vw"
        visible={isModalVisible}
        onOk={handleOk}
        onCancel={handleCancel}
      >
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
      </Modal>

效果:
在这里插入图片描述
至此,方案1基本上已经完成。

方案1瑕疵及解决方案

对于上述方案,有一点点的瑕疵,就是弹窗body部分内容过多,会出现body部分内容超出弹窗窗口进行显示,进而使整个弹窗出现纵向滚动条。对此我们只需要简单的设置一下body部分样式overflowY: "auto"即可,最终代码如下:

      <Modal
        style={{
          maxWidth: "100vw",
          top: 0,
          paddingBottom: 0
        }}
        bodyStyle={{
          height: "calc(100vh - 55px - 53px)",
          overflowY: "auto"
        }}
        title="Basic Modal"
        width="100vw"
        visible={isModalVisible}
        onOk={handleOk}
        onCancel={handleCancel}
      >
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
      </Modal>

完整代码codesandbox地址:https://codesandbox.io/s/antd-modal-fullscreen-z9yz87?file=/demo.js
demo地址:https://z9yz87.csb.app/

方案2:通过修改css样式实现

具体实现思路和方案1类似,只不过该方案是通过修改css样式来实现的。代码如下:

.ant-modal {
  width: 100vw !important;
  max-width: 100vw !important;
  top: 0;
  padding-bottom: 0;
}

.ant-modal-body {
  height: calc(100vh - 55px - 53px);
  overflow-y: auto;
}

完整代码codesandbox地址:https://codesandbox.io/s/antd-modal-fullscreen-css-36ku09?file=/index.css
demo地址:https://36ku09.csb.app/

写在最后

至此,Modal组件的两种全屏实现方案都已经实现完成,希望有兴趣的朋友点个赞👍吧。当然,有想法的朋友也欢迎在评论区交流。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐