最近正在开发自己开源的通用爬虫的前端界面, 用的是 ant-design-pro 进行的二次开发, 遇到的坑还是很多的, 因此接下来分享的内容大多都是和 ant-design 有关的, 经验都来自于自己的填坑之旅. 本篇我们来讲讲怎么实现 Modal 组件的全屏功能.
我们希望实现一下功能
用户能够通过全屏控制图标进行全屏及非全屏操作
支持初始全屏弹窗, 支持隐藏全屏控制图标
寻找图标嵌入点
按照惯例, 全屏控制图标都是放置在弹窗的头部区域, 靠近关闭按钮附近. 在浏览过官方组件使用文档之后, 大致发现有两个地方可以实现此功能.
closeIcon
此属性可以实现自定义关闭图标, 我们在此处可以插入两个图标, 一个用于关闭, 一个用来控制全屏操作, 同时防止全屏操作触发关闭指令, 我们应该在后者的点击事件中阻止事件的冒泡.
title
此属性用来展示标题内容. 我们注意到它不仅支持字符串, 也支持 ReactNode 类型的数据, 因此我们可以在此处实现自定义图标, 并通过样式控制悬浮到头部右侧.
嵌入控制图标
此处我们选择 title 属性来实现, 通过增加一个中间层在用户传入的 title 中添加一个全屏控制弹窗
- const { title } = this.props;
- return (
- <>
- {title}
- <button
- type="button"
- className="ant-modal-close"
- style={{ right: 42 }}
- >
- <span className="ant-modal-close-x">
- <Icon className="ant-modal-close-icon" type="arrows-alt" />
- </span>
- </button>
- </>
- );
上述代码中的全屏控制按钮 copy 自弹窗中的关闭按钮, 唯一的不同就是图标的位置及图标类型. 我们将上述代码封装成一个函数, 将其执行结果赋予 modal 的 title 属性.
实现效果如下:
实现全屏控制功能
上述我们提到要实现用户能够自由控制全屏及退出全屏的功能. 因此我们定义一个名为 fullScreen 的 state 属性来控制当前的弹窗状态.
- // 切换当前全屏状态
- toggleFullScreen = () => {
- const { fullScreen } = this.state;
- this.setState({
- fullScreen: !fullScreen,
- });
- };
- titleRender = () => {
- const { title } = this.props;
- const { fullScreen } = this.state;
- return (
- <>
- {title}
- <button
- type="button"
- className="ant-modal-close"
- style={{ right: 42 }}
- onClick={this.toggleFullScreen}
- >
- <span className="ant-modal-close-x">
- <Icon className="ant-modal-close-icon" type={fullScreen ? 'shrink' : 'arrows-alt'} />
- </span>
- </button>
- </>
- );
- };
同时我们希望通过 CSS 来控制全屏的样式, 因此我们需要通过上述 fullScreen 来给予 modal 不同的样式名.
- const { fullScreen } = this.state;
- render() {
- <Modal
- wrapClassName={`${fullScreen ? 'modal-wrap-fullscreen' : ''}`}
- title={this.titleRender()}
- {...REST}
- />
- }
上述代码我们通过 modal-wrap-fullscreen 来控制全屏的时候的样式, 这边需要 CSS 控制的样式主要有:
控制 modal 高度为浏览器可视区域高度, 这边可以通过 100vh 来实现, 宽度为 100% 即可
控制 modal 的 body 高度为浏览器可视区域高度 - 头部区域高度 - 底部区域高度. 这边如果需要实现无底部区域等情况, 还可以继续细分赋予 Modal 不同的 wrapClassName 来控制
可以将边角由圆角改成直角
其它控制参数
默认全屏功能
要实现默认全屏功能, 那么用户得传入一个参数表明默认全屏. 此处我们同样在 props 增加一个参数名为 fullScreen 的参数, 并且 state 中的初始值由 props 中的参数决定即可.
隐藏控制图标
同样我们增加一个名为 maxmin 的属性来控制
- titleRender = () => {
- const { title, maxmin } = this.props;
- const { fullScreen } = this.state;
- return (
- <>
- {title}
- {maxmin && (
- <button
- type="button"
- className="ant-modal-close"
- style={{ right: 42 }}
- onClick={this.toggleFullScreen}
- >
- <span className="ant-modal-close-x">
- <Icon className="ant-modal-close-icon" type={fullScreen ? 'shrink' : 'arrows-alt'} />
- </span>
- </button>
- )}
- </>
- );
- };
结语
上述代码只是为了说明实现思路作为参考, 可能并不完整. 详细可以查看我托管的代码, 当然我封装的代码中实现的功能会更多一点, 具体可以看这.
来源: http://www.jianshu.com/p/30f280fb5f9b