前端的中后台管理系统相比于其他普通项目,从开发设计的角度来说有几点比较特殊:

  • 一个是权限设计,具体实现可参考:传送门。
  • 一个是页面布局的设计,也是本文要说的。一个好的页面布局设计,无论是对于页面结构的稳定性,还是功能拓展的方便性,亦或是用户体验上,都有着重要的作用。

一、市面参考

先来看看市面上的一些优秀的开源系统项目的页面布局。

1、vue-element-admin

vue-element-admin 是 vue 框架的一个优秀的后台管理系统开源项目,目前star数75k。

vue-element-admin采用的是侧边菜单布局,侧边菜单 + 顶部导航 + 内容区域,这也是我个人最推崇的布局方式。

2、ant design pro

ant design pro 有提供三种布局。

(1)顶部菜单布局

即:顶部导航菜单 + 内容区域。

这种方式布局简单,但缺点很明显,菜单都挤在顶部导航区域,在菜单项越来越多时就放不下了,很难处理,可扩展性不强。

(2)侧边菜单布局

侧边菜单 + 顶部导航 + 内容区域。

同vue-element-admin类似,主要区别就是antd pro的面包屑导航是另起一行单独放的,这样挤压了内容区域的空间,个人觉得还是放在顶部和右上角的快捷按钮放同一行最好。

(3)混合菜单布局

其实和侧边菜单布局大同小异,还是属于侧边菜单布局的范畴。

只不过这样布局的话,面包屑导航就不适合和顶部放一行了,只能另起一行。

二、选型

参考市面上比较优秀的两款项目模板的布局后,个人还是觉得vue-element-admin的布局方式更胜一筹。

文本就围绕这种布局结构来设计。

  • 示例项目:react-antd-mobx-admin
  • 技术栈:react 17 + antd 4 + react-router-dom 6 + ts
  • 路由统一管理使用 react-router-waiter 方案

效果图:

其实技术选型不那么重要,无论是react还是vue,element或是antd,思路一致,都只是实现代码的差异而已。

对于侧边栏菜单和面包屑导航,element和antd都有相应的组件可以直接使用,其他的手写实现。

三、css布局

良好的css布局代码才能保证页面布局的稳定性。

而对于整体布局来说,flex是首选,稳定性更好,不兼容ie9。

这里将整体布局封装成组件PageLayout

(1)首先,设置侧边栏右侧的盒子撑满屏幕剩余宽度。
flex布局有个特性是:只对一个子元素设置flex: 1属性时,该子元素默认会撑满父容器的剩余空间。

.c-PageLayout-index {width: 100%;height: 100%;display: flex;.appMainWrap {height: 100%;flex: 1; // 占据屏幕剩余宽度position: relative;padding-top: 50px; // 留出顶部导航栏区域,顶部导航栏使用悬浮置顶。}.appMain {height: 100%;overflow: auto;padding: 15px; // 内容区域可以在这里统一设置下边距}
}
  • c-PageLayout-index 页面整体容器
  • appMainWrap 侧边栏右侧的(顶部导航区域 + 内容区域)容器
  • appMain 内容区域容器

(2)侧边菜单区域默认撑满高度,宽度可交给antd组件自适应,也可以自己设死。

.c-PageLayout-sideBar {height: 100%;overflow: auto;
}

(3)顶部导航区域悬浮置顶。

.c-PageLayout-headBar {height: 50px;display: flex;justify-content: space-between;position: absolute;top: 0;right: 0;width: 100%;
}

四、侧边栏菜单

侧边栏的实现方式是难点,因为这里即涉及到如何和路由数据匹配,又涉及权限的筛选。

侧边栏最好是和路由配置共用一套数据,方便扩展和维护,这里得益于 react-router-waiter 已经封装好的路由管理方案(类vue-router),所以直接读取路由配置数据,动态生成菜单组件结构。

路由配置数据:

import PageLayout from '@/components/PageLayout'
import { HomeOutlined } from '@ant-design/icons'const routes: RoutesTypeNew = [{path: '/',element: <PageLayout />,children: [{path: 'index',component: () => import(/* webpackChunkName: "index" */ '@/views/index/index'),meta: {title: '首页',icon: <HomeOutlined />,accessId: '10000',}},]},
]
  • 如有点击跳转外链的菜单场景,可以在routes里添加个自定义的配置对象,例如通过url属性指代外链地址。

动态生成菜单:

// 递归获取层级菜单
function getMenuList () {const getList: any = (routeList = [], prePath = '') => {let menuList: JSX.Element[] = []routeList.forEach((v: RoutesItemTypeNew) => {if (v.path === '/') {menuList = menuList.concat(getList(v.children, '/'))} else {const currentPath = prePath + v.pathif (v.children) {menuList.push((<SubMenu key={currentPath} icon={v.meta.icon} title={v.meta.title}>{getList(v.children, currentPath + '/')}</SubMenu>))} else {menuList.push((<ItemMenu key={currentPath} icon={v.meta.icon}><Link to={currentPath}>{v.meta.title}</Link></ItemMenu>))}}})return menuList}return getList(routes)
}
  • 如需要对权限路由做筛选,通过在路由配置数据meta里添加accessId字段作为路由权限id,然后在遍历routeList时,读取该accessId做权限判断。

五、面包屑导航

要使用面包屑导航,需要对路由路径配置有一定的约束规则,即,配置path路径时不要随意使用斜杠/划分,只通过嵌套路径自动划分路径。

这样才能对路由完整路径通过/分隔并匹配,来生成对应的面包屑导航数据。

首先,写个方法,遍历路由,生成路由路径和路由meta字段的映射数据:

function getRouteMetaMap () {const getMap: any = (routeList = [], prePath = '') => {let map = {}routeList.forEach((v: RoutesItemTypeNew) => {let currentPath = prePath + v.pathif (v.path === '/') {currentPath = ''} else {map = {...map,[currentPath]: v.meta || {}}}if (v.children) {map = {...map,...getMap(v.children, currentPath + '/')}}})return map}return getMap(routes)
}
  • 映射数据示例:

    {"/index": {"title": "首页","accessId": "10000"},"/nest": {"title": "多级菜单",},"/nest/nest1": {"title": "二级菜单1"},"/nest/nest1/nest11": {"title": "三级菜单11"}
    }
    

然后,获取当前路由完整路径(例如:/nest/nest1/nest11),再通过/分隔成多段子路由,和上述getRouteMetaMap方法取到的映射数据匹配,获取子路由的title标题组合成面包屑(多级菜单 / 二级菜单1 / 三级菜单11),展示出来。

const routeMetaMap = getRouteMetaMap()
const pathSnippets = location.pathname.split('/').filter(i => i)
const extraBreadcrumbItems = pathSnippets.map((_, index) => {const url = `/${pathSnippets.slice(0, index + 1).join('/')}`return (<Breadcrumb.Item key={url}><span>{routeMetaMap[url].title}</span></Breadcrumb.Item>)
})

本文示例项目源码:react-antd-mobx-admin


参考链接:
https://panjiachen.gitee.io/vue-element-admin/
https://preview.pro.ant.design/form/basic-form

后台管理系统 - 页面布局设计相关推荐

  1. vue+element-ui搭建简易的后台管理系统页面布局

    工作中一直用element-ui写中后台项目,所以决定写一个vue+element-ui搭建简易的后台管理页面框架教程,可以快速搭建好简单的中后台界面.完成后显示如下 用vue-cli构建项目 必须之 ...

  2. 使用bootstrap搭建后台管理系统页面《一》

    1. 使用bootstrap搭建后台管理系统页面<一> 一般的后台管理系统页面主体包括四个部分,顶部导航栏,左侧菜单栏,中间正文页和底部的页脚. 其中左侧和顶部使用的是bootstrap的 ...

  3. 后台管理系统的布局框架

    1.HTML部分 <!DOCTYPE html> <html> <head><meta charset="utf-8"><ti ...

  4. 后台管理页面布局(左侧导航长度根据右侧内容无限延伸)

    2019独角兽企业重金招聘Python工程师标准>>>     如图为标准后台管理页面布局,左侧导航布局一般是设置高度100%来适应所有尺寸的显示器打开的浏览器高度. 但是这种布局会 ...

  5. 讲解后台管理系统之列表设计分享

    我们大家都知道,在后台管理系统中列表设计一直是重中之重,因为它承载了用户想看.重要且关键的业务信息,所以设计时要格外注意信息降噪,让用户能够快速找到想看的信息,切勿盲目摆放,这里我也收集了一些注意的点 ...

  6. 使用bootstrap搭建后台管理系统页面《二》

    1.使用bootstrap搭建后台管理系统页面<二> 这次不需要另外写css.直接完全引用bootstrap下的样式. 完成以后的效果: 源代码: <%@ page language ...

  7. 【VUE】demo01-VUE做后台管理系统页面实例-创建基本环境+页面布局

    目录 1.1vue cil2创建初始化项目 1.2引入项目使用的模块并运行 1.3修改静态路由router 1.4自定义的layout布局 工具:Visual Studio Code + Vue + ...

  8. 框架技术Vue --- 路由、后台管理系统页面

    Vue框架 内容管理 前端路由 前端路由的工作方式 实现简易的前端路由 created中window.onhashchange vue-router基本使用 router-link的hash地址不需要 ...

  9. 应用css div进行页面布局设计,利用CSS与DIV进行页面布局.ppt

    <利用CSS与DIV进行页面布局.ppt>由会员分享,可在线阅读,更多相关<利用CSS与DIV进行页面布局.ppt(6页珍藏版)>请在人人文库网上搜索. 1.利用CSS与DIV ...

  10. 专题地图的编制(一)页面布局设计

    [1]启动ArcMap,新建空白地图文档: [2]打开[目录]窗口,定位到[4-Data]->[Symbology.mxd],双击打开地图文档: [3]插入数据框.单击菜单[插入]->[数 ...

最新文章

  1. 避免HttpClient的”javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated”异常
  2. AI基础:数据划分、超参数调整、正则化
  3. 关于SparkMLlib的基础数据结构Spark-MLlib-Basics
  4. Excel如何处理x,y坐标的合并
  5. POJ-3061 Subsequence 二分或尺取
  6. CentOS7 扩容时发现 /dev/mapper/centos-home 不存在,创建后登录终端显示 -bash-4.2
  7. nginx配置ssl证书的方法
  8. 从远程库克隆(转载)
  9. 用.NET提供的Mail来发邮件
  10. 在win10下安装Linux双系统
  11. Apache配置虚拟主机
  12. 小觅双目相机如何使用_小觅双目摄像头是怎样的产品?
  13. 牵手爱情,绎一份不了情缘
  14. 解决“error: failed to push some refs to ‘git@gitee.com:username/repo.git‘“
  15. SQLSERVER Agent XPs disable
  16. linux 搜狗拼音 自动隐藏状态栏
  17. docker启动jenkins部署springboot到tomcat(集成:企业微信和邮件通知)
  18. python如何调用谷歌搜图api_python爬虫——selenium+chrome使用代理
  19. 守株待兔欧洲游-法国(9.30-10.5)(已完工)
  20. Violent Flows violence recognition 数据集地址下载

热门文章

  1. sql分组排序, 分页查询
  2. CIM+规划:自带CIM平台的数字规划咨询服务,提升城市空间价值和产业活力
  3. Visual Stdio 无法找到资源编译器DLL
  4. 『开发』小程序通过易班接口登陆并请求数据
  5. 路飞学城Python-Day1
  6. android 设置gps波特率,GPS端口、波特率设置原理详解(GPS如何搜星,波特率对传输速度和精度的影响)...
  7. in use 大学英语4word_(完整word版)全新版大学英语第四册综合教程课后翻译答案及课文译文...
  8. ValueError: operands could not be broadcast together with shapes (100,) (71,)
  9. usb计算机连接文件,学习两种方式使用USB在计算机之间传输文件!
  10. 如何在Mac上恢复未保存的word文档