🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
&emsp;&emsp;为了提升业务人员操作管理后台的体验,花了点时间进行响应式的改造,紧急情况时,掏出手机就能工作。 &emsp;&emsp;利用CSS3的媒体查询,就能根据不同屏幕的尺寸采用不同的样式来渲染,目前使用的移动端屏幕阈值为750px。 &emsp;&emsp;为了便于管理,基于[Less](https://lesscss.org/)的语法,声明了一个常量,专门记录屏幕尺寸。 ~~~css @mobile-screen: ~"(max-width:750px)"; ~~~ &emsp;&emsp;我们当前使用的管理后台基于[UmiJS3.X](https://umijs.org/zh-CN)和[Ant Design 3.X](https://3x.ant.design/docs/react/introduce-cn)。 ## 一、结构改造 &emsp;&emsp;首先是管理后台整体结构的改造,包括左边的菜单栏,右边的快捷按钮,登录信息等。 :-: ![](https://img.kancloud.cn/01/2f/012fbae6d36f9b6de9aeab23d55f2793_3220x848.png =800x) **1)菜单栏** &emsp;&emsp;左边的菜单在手机界面还是蛮占地方的,默认情况下需要将其隐藏,还有那张Logo图,也需要隐藏,最大限度的将区域留给菜单。 &emsp;&emsp;在下面的代码中,当URL的路径发生变化时,判断屏幕尺寸,如果当前是显示状态,那么就更新成隐藏状态。 ~~~ // 响应式处理 const mobileHandle = () => { // 屏幕尺寸小于750的就认为是移动设备的屏幕 if (window.screen.width <= 750 && !siderFold) { dispatch({ type: "app/switchSider" }); } }; // 当路径变化时,隐藏菜单栏 useEffect(() => { mobileHandle(); }, [location.pathname]); ~~~ &emsp;&emsp;在Chrome的控制台,切换成手机屏幕时,右半部分会出现挤压的问题。 :-: ![](https://img.kancloud.cn/59/e6/59e6c08766b44d25f160d82d84654825_750x1054.png =300x) &emsp;&emsp;可以将右半部分设置为绝对定位,脱离正常流,再向左偏移菜单栏的宽度就能避免内容被挤压。 ~~~css .main { width: 100%; position: absolute; left: 250px; } ~~~ **2)快捷按钮** &emsp;&emsp;快捷按钮有3个,PC界面这块的高度是固定的,并且是横向布局。移动端的屏幕比较窄,更适合纵向布局。 &emsp;&emsp;并且为了节约空间,登录后的昵称,也隐藏了,免得破坏布局。 :-: ![](https://img.kancloud.cn/9e/96/9e9635ea8660249794c9b9f0ae78ebb3_740x264.png =400x) **3)全局样式** &emsp;&emsp;这些按钮默认是没有上下间距的,需要手动添加,例如修改Ant Design 的下拉框、搜索框、日期选择框的下边距,存储在 global.css 文件中。 ~~~css .ant-select, .ant-input-search, .ant-calendar-picker { margin-bottom: 5px; } ~~~ &emsp;&emsp;有一点需要注意,不能将上述这些样式写在 less 文件内,因为在JavaScript文件中引用(CSS in JS)时,默认会带各种随机后缀。 ~~~css @media @mobile-screen { .ant-select, .ant-input-search { margin-bottom: 5px; } } /* 编译结果 */ @media (max-width: 750px) { .ant-select___1JpXW, .ant-input-search___WeNgK { margin-bottom: 5px; } } ~~~ &emsp;&emsp;全局声明需要权衡,当涉及的页面很多时,也许某条样式会破坏某处的结构。 ## 二、页面改造 &emsp;&emsp;在页面中使用了大量的组件,包括自定义和第三方的,默认情况下,都不支持响应式,需要进行手动改造。 **1)表格** &emsp;&emsp;管理后台包含很多表格,这些表格都会包含很多列,直接平铺会将页面撑开,出现左右滚动条。 &emsp;&emsp;在观察Ant Design表格滚动的源码后,发现了一个 max-content 关键字,表示宽度就是内容的长度。 ~~~css .ant-table-body, /* 表格 */ .ant-tabs-tabpane { /* 标签栏切换内容 */ overflow-x: scroll; width: 100%; -webkit-overflow-scrolling: touch; } .ant-table-body table, .ant-tabs-tabpane table { width: max-content; } ~~~ &emsp;&emsp;在表格的父级元素中声明横向滚动,就能避免布局被破坏了。 :-: ![](https://img.kancloud.cn/67/f1/67f177a8ab8902ce71687a495215952a_724x612.png =400x) **2)内联样式** &emsp;&emsp;在之前的页面开发中,很多组件的宽度都是以内联的方式声明的。当时的确很方便,但是现在改造给我制造了障碍。 &emsp;&emsp;如果直接在CSS文件中声明,那么特殊性不会比内联的高,也就不会生效,所以得用另一种方式。 &emsp;&emsp;后面就想用脚本来做样式的更新,脚本比较好写。但是需要考虑一种情况。 &emsp;&emsp;那就是页面初始化时不存在的DOM元素,需要点击或其他交互后才能被添加进来。 &emsp;&emsp;需要监听DOM的变化,自然就想到了[MutationObserver](https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver),在下面的代码中会监听 body 元素的直系后代的DOM变化。 ~~~ useEffect(() => { const isMobile = window.screen.width <= 750; // 选择器,数字框,文本框,卡片 const selector = ".ant-input-number[style],.ant-input[style],.ant-calendar-picker[style],.ant-card[style],.ant-input[style]"; if (!isMobile) return; const callback = function (mutationsList, observer) { // 为了响应式,将style中的宽度修改成 100% const nodes = document.querySelectorAll(selector); [...nodes].forEach((item) => { if (item.style.width && item.style.width != "100%") { item.style.width = "100%"; } }); }; // 观察器的配置,直接子节点的更改 const config = { childList: true }; const observer = new MutationObserver(callback); // 观察目标节点 observer.observe(document.body, config); }, []); ~~~ **3)弹框** &emsp;&emsp;在PC界面中,弹框中的内容会比较多,高度也会被撑开。 &emsp;&emsp;当在移动端显示时,会超过屏幕的底部,无法看到弹框中的内容。 &emsp;&emsp;可以手动的声明弹框的高度,利用[calc()](https://developer.mozilla.org/zh-CN/docs/Web/CSS/calc)函数,以及vh单位,100vh就是视口高度的100%。 ~~~css height: calc(100vh - 100px) ~~~ ***** > 原文出处: [博客园-CSS躬行记](https://www.cnblogs.com/strick/category/1667864.html) [知乎专栏-CSS躬行记](https://zhuanlan.zhihu.com/pwcss) 已建立一个微信前端交流群,如要进群,请先加微信号freedom20180706或扫描下面的二维码,请求中需注明“看云加群”,在通过请求后就会把你拉进来。还搜集整理了一套[面试资料](https://github.com/pwstrick/daily),欢迎浏览。 ![](https://box.kancloud.cn/2e1f8ecf9512ecdd2fcaae8250e7d48a_430x430.jpg =200x200) 推荐一款前端监控脚本:[shin-monitor](https://github.com/pwstrick/shin-monitor),不仅能监控前端的错误、通信、打印等行为,还能计算各类性能参数,包括 FMP、LCP、FP 等。