后台管理系统 - 页面布局设计

news2024/11/18 17:20:35

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

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

一、市面参考

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

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.path
        if (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.path
      if (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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/409467.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java Web实现登录注册(超详细附代码)

Java Web实现登录注册&#xff08;超详细附代码&#xff09; 文章目录Java Web实现登录注册&#xff08;超详细附代码&#xff09;1.前言2.登录注册设计流程3.注册的数据流程4.登录的数据流程5.部分代码的展示5.1注册5.2登录6.总结1.前言 相信刚学Javaweb的小伙伴第一个接触的…

30个极致实用的谷歌浏览器插件,让你开发事半功倍

浏览器是开发人员最强大的工具。99% 的人不会 100% 地利用他们的浏览器。这里有 30 个浏览器扩展&#xff0c;如果你能合理充分利用将大大提升你的开发效率。1. WhatFont"WhatFont"&#xff0c;是一款帮助用户快速识别网页中字体信息的工具。当你在浏览网页时&#x…

vue|axios发送post请求详解

axios发送Post请求 首先我们要知道发送一个请求体的时候我们要明确发送的类型是什么&#xff0c;常见的类型有三种 form-dataapplication/jsonapplication/x-www-form-urlencoded 以上三种类型是进行数据传输的数据类型&#xff0c;我们知道在js代码中的对象都不是以上的三种…

react实现路由跳转

react通过路由实现页面跳转&#xff1a; ​ 函数式路由(withRouter)使用原生js方法实现路由功能。 ​ eg&#xff1a;export default withRouter(Home) Home是组件名称。 示例&#xff1a;class Home extends Component{<button onClick{this.goForward}>下一级</bu…

猿创征文|【C++游戏引擎Easy2D】炫酷动画来这学,位移动画构造函数让节点执行动画

&#x1f9db;‍♂️iecne个人主页&#xff1a;&#xff1a;iecne的学习日志 &#x1f4a1;每天关注iecne的作品&#xff0c;一起进步 &#x1f4aa;学C必看iecne 本文专栏&#xff1a;【C游戏引擎】. &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; ✨前…

from origin ‘null‘ has been blocked by CORS policy: Cross origin requests are only supported for ...

跨源资源请求问题解决方案 问题描述&#xff1a;当我们在vsCode中使用 open in brower插件打开html文件文件时&#xff0c;就会报错 xxx已被CORS策略阻止&#xff0c;引入的资源还会失效。 解决办法1 :Live Server插件 在vsCode的插件市场中搜索并安装Live Server插件&#x…

Axios

Axios是Ajax的一个框架&#xff0c;简化Ajax操作 一、基本操作 Axios执行Ajax的操作&#xff1a; 1. 添加axios的js文件 <script language"JavaScript" src"script/axios.min.js"></script> 2.1 客户端向服务端异步发送普通参数值 格式&am…

vue-router报错: uncaught error during route navigation

bug场景&#xff1a; H5项目中,浏览器流程走的通,ios流程走得通,安卓机有的可以有的不行 报错信息&#xff1a; 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 例如&#xff1a;数据传输过程中数据不时出现丢失的情况&#xff0c;偶尔会丢失一部分数据 APP 中接收数…

尚融宝06-ECMAScript基本介绍和使用

目录 一、ECMAScript 1、ECMA 2、ECMAScript 3、什么是 ECMA-262 4、ECMA-262 历史 5、ECMAScript 和 JavaScript 的关系 二、基本语法 1、let声明变量 2、const声明常量 3、解构赋值 4、模板字符串 5、声明对象简写 6、定义方法简写 7、参数的默认值 8、对象拓…

less变量

Less变量一、Less简介二、Less中的变量三、less外部引入一、Less简介 1.Less是一门css的预处理语言&#xff0c;less是一个css的增强版&#xff0c;通过less可以编写更少的代码实现更强大的样式。 变量名以两条短横线命名 例如&#xff1a; --color&#xff1a;red 2.Less特…

vue的created函数中方法执行的顺序设置方法

1.vue的created钩子函数中&#xff0c;方法的执行顺序 1.1情景&#xff1a;vue框架中通常在created钩子函数里执行访问数据库的方法&#xff0c;然后返回数据给前端&#xff0c;前端data中定义全局变量接收数据 1.2误区&#xff1a;我们可能会思考按照自己设定好的逻辑走&…

使用uni-app的uni.chooseImage获取的图片路径,存储到数据库中,无法在前端展示该路径的图片

html,js,uni-app, 首先我在uni-app中使用如下方法添加图片 uni.chooseImage({count: 1, //count: 6, //默认9sizeType: [original, compressed], //可以指定是原图还是压缩图&#xff0c;默认二者都有sourceType: [album], //从相册选择success: function(res) {console.log(…

【vue2】vue2中的性能优化(持续更新中)

⭐ v-for 遍历避免同时使用 v-if ⭐ v-for 中的key绑定唯一的值 ⭐ v-show与v-if对性能的影响 ⭐ 妙用计算属性 ⭐ 使用防抖与节流控制发送频率 ⭐ 路由守卫处理请求避免重复发送请求 ⭐ 使用第三方UI库的引入方式 【前言】 该系列是博主在使用vue2开发项目中常用上的一…

JavaScript ,18种常用数组方法,快来看看你会吗?

前言 众所周知&#xff0c;向后端请求数据&#xff0c;处理数据是前端工程师必备的技能&#xff0c;从后端请求回来的数据往往是数组的形式返回到前端&#xff0c;因此数组处理方法的重要性可想而知&#xff1b;数组的处理方法在MDN文档上很多&#xff0c;很多朋友在学习时往往…

vue配置代理服务器proxy

一、跨域。 跨域本质是浏览器基于同源策略的一种安全手段 所谓同源&#xff08;即指在同一个域&#xff09;具有以下三个相同点 协议相同&#xff08;protocol&#xff09;主机相同&#xff08;host&#xff09;端口相同&#xff08;port&#xff09; 非同源请求&#xff0c…

vue集成海康h5player实现播放

文章目录前言准备工作视频demo官方文档官方工具开源工具开始开发效果问题点前言 本篇章只针对官方提供个h5player工具&#xff0c;做播放和分屏demo。 当然本篇章也是针对已经接触了海康视频对接的开发者。 准备工作 视频demo 官方文档 API https://open.hikvision.com/d…

Not allowed to load local resource: file:///,浏览器禁止访问浏览器图片,文件解决方法

Not allowed to load local resource: file… 错误出现原因&#xff1a;浏览器出于安全考虑禁止直接读取本机文件(链接以file:///开头)&#xff0c; 解决办法&#xff1a; 创建一个web服务器&#xff0c;将文件放在这个服务器里&#xff0c;让文件有一个在线地址&#xff08…

【小程序项目开发-- 京东商城】uni-app之商品列表页面 (下)

&#x1f935;‍♂️ 个人主页: 计算机魔术师 &#x1f468;‍&#x1f4bb; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f310; 推荐一款找工作神器网站: 点击跳转牛客网 |笔试题库|面试经验|实习招聘内推| 还没有账户的小伙伴 速速点击链接…

推荐几个优秀的echarts 图表网站,让你轻松搞定全部报表

1.PPChart - 让图表更简单让图表更简单。PPChart 提供 Echarts 收录、图表制作等服务http://ppchart.com/#/ 2.https://madeapie.com/#/echarts图表制作&#xff0c;Make A Pie&#xff0c;Made A Pie&#xff0c;echarts案例分享&#xff0c;echarts教程分享https://madeapie…

PHP连接数据库MySQL打造xxx管理系统,实现简单的增删改查功能

目录 前言 概述 内容 创建数据库表 实现列表 新增用户 删除用户 编辑用户 前言 最近刚学完PHP和Mysql,历时半个多月时间完成了这样一个简单的算是人员管理系统吧&#xff0c;为了加深印象总结一下&#xff0c;还有很多不足之处&#xff0c;希望大家多多指正&#xff0c;一…