为了提升业务人员操作管理后台的体验,花了点时间进行响应式的改造,紧急情况时,掏出手机就能工作。

  利用CSS3的媒体查询,就能根据不同屏幕的尺寸采用不同的样式来渲染,目前使用的移动端屏幕阈值为750px。

  为了便于管理,基于Less的语法,声明了一个常量,专门记录屏幕尺寸。

@mobile-screen: ~"(max-width:750px)";

  我们当前使用的管理后台基于UmiJS3.XAnt Design 3.X

一、结构改造

  首先是管理后台整体结构的改造,包括左边的菜单栏,右边的快捷按钮,登录信息等。

  

1)菜单栏

  左边的菜单在手机界面还是蛮占地方的,默认情况下需要将其隐藏,还有那张Logo图,也需要隐藏,最大限度的将区域留给菜单。

  在下面的代码中,当URL的路径发生变化时,判断屏幕尺寸,如果当前是显示状态,那么就更新成隐藏状态。

// 响应式处理
const mobileHandle = () => {
// 屏幕尺寸小于750的就认为是移动设备的屏幕
if (window.screen.width <= 750 && !siderFold) {
dispatch({
type: "app/switchSider"
});
}
};
// 当路径变化时,隐藏菜单栏
useEffect(() => {
mobileHandle();
}, [location.pathname]);

  在Chrome的控制台,切换成手机屏幕时,右半部分会出现挤压的问题。

  

  可以将右半部分设置为绝对定位,脱离正常流,再向左偏移菜单栏的宽度就能避免内容被挤压。

.main {
width: 100%;
position: absolute;
left: 250px;
}

2)快捷按钮

  快捷按钮有3个,PC界面这块的高度是固定的,并且是横向布局。移动端的屏幕比较窄,更适合纵向布局。

  并且为了节约空间,登录后的昵称,也隐藏了,免得破坏布局。

  

3)全局样式

  这些按钮默认是没有上下间距的,需要手动添加,例如修改Ant Design 的下拉框、搜索框、日期选择框的下边距,存储在 global.css 文件中。

.ant-select,
.ant-input-search,
.ant-calendar-picker {
margin-bottom: 5px;
}

  有一点需要注意,不能将上述这些样式写在 less 文件内,因为在JavaScript文件中引用(CSS in JS)时,默认会带各种随机后缀。

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

  全局声明需要权衡,当涉及的页面很多时,也许某条样式会破坏某处的结构。

二、页面改造

  在页面中使用了大量的组件,包括自定义和第三方的,默认情况下,都不支持响应式,需要进行手动改造。

1)表格

  管理后台包含很多表格,这些表格都会包含很多列,直接平铺会将页面撑开,出现左右滚动条。

  在观察Ant Design表格滚动的源码后,发现了一个 max-content 关键字,表示宽度就是内容的长度。

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

  在表格的父级元素中声明横向滚动,就能避免布局被破坏了。

  

2)内联样式

  在之前的页面开发中,很多组件的宽度都是以内联的方式声明的。当时的确很方便,但是现在改造给我制造了障碍。

  如果直接在CSS文件中声明,那么特殊性不会比内联的高,也就不会生效,所以得用另一种方式。

  后面就想用脚本来做样式的更新,脚本比较好写。但是需要考虑一种情况。

  那就是页面初始化时不存在的DOM元素,需要点击或其他交互后才能被添加进来。

  需要监听DOM的变化,自然就想到了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)弹框

  在PC界面中,弹框中的内容会比较多,高度也会被撑开。

  当在移动端显示时,会超过屏幕的底部,无法看到弹框中的内容。

  可以手动的声明弹框的高度,利用calc()函数,以及vh单位,100vh就是视口高度的100%。

height: calc(100vh - 100px)

最新文章

  1. 10套免费的 Photoshop UI 元素以及 PSD 素材
  2. 【转】关于.net framework4.0以及4.5安装失败,“安装时发生严重错误”……
  3. 更改RAC日志组
  4. CountDownLatch,CyclicBarrier,Semaphore
  5. slf4j提示Class path contains multiple SLF4J bindings
  6. Java compiler level does not match the version of the installed Java project facet. springmvc1 和 Target runtime Apache Tomcat v7.0 is not defined.
  7. selenium for python 所有方法
  8. centos 源码安装git
  9. 把自定义控件集成到Qt Designer中
  10. vue+mockjs 模拟数据,实现前后端分离开发
  11. PS 滤镜算法原理——染色玻璃
  12. mysql报错mmap(137428992 bytes) failed; errno 12,Cannot allocate memory for the buffer pool
  13. 从koa-session源码解读session本质
  14. Linux环境下Hadoop集群搭建
  15. java集合框架-List集合ArrayList和LinkedList详解
  16. 005.Ceph文件系统基础使用
  17. (Detected problems with API compatibility(visit g.co/dev/appcompat for more info)
  18. Windows hackson (rundll32--ADS)
  19. HashMap中的hash函数
  20. spring boot 学习入门篇【spring boot项目的搭建以及如何加载jsp界面】

热门文章

  1. SpringMVC常用的注解有哪些?
  2. prometheus-存储
  3. 列举 IoC 的一些好处?
  4. leetcode_两数相加
  5. 攻防世界 easytornado
  6. L298N双H桥集成电路板的双H桥是什么意思?为什么要叫双H桥?L298N工作原理
  7. LQR (线性二次型调节器)的直观推导及简单应用
  8. web app遇到的一些坑及小技能(持续更新...)
  9. 基于腾讯开源的msec来进行php开发模块
  10. Unity中让Update中的方法执行一次