前端应用界面的展示与优化(记录)

情景:由于项目要分期上线,并且数据库中删除是改变删除标识而id不发生改变,分期上线时会先展示部分功能,后期再加上新菜单时与本地环境的数据库id不同将导致列表展示有误,故选择将根据id展示改成根据菜单标识名来匹配。由于不同模块的子应用展示时会有不同的判定条件,为了减少逻辑上的判断和加快逻辑将由遍历本地静态路由和请求返回的动态路由完成比对后显示的方式改为将返回的树结构中的标识名称取出,再将本地的树形路由改为平面数组的形式,完成比对后将数组转成树形结构,只能说比一个个去遍历和判断方便的多。。。

这个界面主要分三个部分,设备、航班是可以直接根据系统中的路由来显示的,任务管理中的功能是要根据用户权限现实的,学习园地,设备档案,智慧运营这三个是在跟设备,航班同级的应用模块下的子功能,这就导致了整个页面要实现动态展现要进行三种判断。

先放上第一种,直接看数据库根据数据库中的id来判断,由于pc端删除菜单时是不会去删库数据而是改标识id,所以直接根据id来判定是可行的。(后期才发现问题多多。。。)

前端部分由于要配合左侧的模块实现点击模块名右侧功能实现自动定位所以整体的结构与后端返回的路由并不能一一对应。

后端返回形式

前端实际的形式

如上文所说,应用部分与返回部分不是同级,任务部分并不根据实际返回的路由显示而是进行二次判断。

方法一:根据id判断,优:操作简单 缺:如果上线过程中创建菜单过程不一样也就是菜单部分建库时不带数据将导致菜单混乱。逻辑判断冗杂

静态路由写死,遍历返回的菜单根据id去判断

静态:

javascript 复制代码
								applicationList: [{
						"title": this.$t('DeviceManagement'),
						"id": "DeviceManagement",
						"menu": 2,
						"showModel": false,
						"menuName": "设备",
						"list": [{
								"showItem": false,
								"menu": 23,
								"title": this.$t('AllDevice'),
								"title_initial": "B",
								"name": "Repair",
								"icon": this.$mAssetsPath.allEqp,
								"group": "device",
								"url": "/pages/application/Device/index?navIndex=0&statusCurrent=1&menu=23"
							},
							{
								"showItem": false,
								"menu": 23,
								"title": this.$t('AlarmDevice'),
								"title_initial": "B",
								"name": "Repair",
								"icon": this.$mAssetsPath.alarmEqp,
								"group": "device",
								"url": "/pages/application/Device/index?navIndex=0&statusCurrent=0&menu=23"
							},
							{
								"menu": 24,
								"title": this.$t('HistoryQuery'),
								"title_initial": "B",
								"name": "Repair",
								"icon": this.$mAssetsPath.getHistory,
								"group": "device",
								"url": "/pages/application/Device/index?navIndex=1&menu=24"
							},
							{
								"menu": 25,

								"title": this.$t("DeviceSet"),
								"title_initial": "B",
								"name": "Repair",
								"icon": this.$mAssetsPath.eqpSetting,
								"group": "approve",
								"url": "/pages/application/Device/index?navIndex=2&menu=25"
							},
							{
								"menu": 26,
								"title": this.$t('FaultReport'),
								"title_initial": "B",
								"name": "Repair",
								"icon": this.$mAssetsPath.faultReporting,
								"group": "device",
								"url": "/pages/application/Device/index?navIndex=3&menu=26"
							}
						]
					}, {
						"title": this.$t("Flight"),
						"id": "Flight",
						"menu": 3,
						"showModel": false,
						"menuName": "航班",
						"list": [{
								"menu": 21,
								"title": this.$t('FlightInfo'),
								"title_initial": "C",
								"name": "flightInfo",
								"icon": this.$mAssetsPath.flightInfo,
								"group": "flight",
								"url": "/pages/application/Flight/" + mConstDataConfig.airportSignage +
									"/Flight?radio=0"
							},
							{
								"menu": 22,
								"title": this.$t('FlightFocused'),
								"title_initial": "C",
								"name": "favFlight",
								"icon": this.$mAssetsPath.favFlight,
								"group": "flight",
								"url": "/pages/application/Flight/" + mConstDataConfig.airportSignage +
									"/Flight?radio=1"
							},
							{
								"menu": 404,
								"title": "写入nfc",
								// "title_initial": "C",
								"name": "Car",
								"icon": this.$mAssetsPath.writeNFC,
								"group": "flight",
								"url": "/pages/application/Flight/" + mConstDataConfig.airportSignage +
									"/addNFC/addNFC"
							}
						]
					}, {
						"menu": 4,
						"showModel": false,
						"title": this.$t("TaskManagement"),
						"id": "TaskManagement",
						"menuName": "任务",
						"list": [{
							"title": this.$t("RepairTask"),
							"title_initial": "J",
							"name": "Rewards",
							"icon": this.$mAssetsPath.maintenance,
							"group": "task",
							"url": "/pages/application/works/" + mConstDataConfig.airportSignage +
								"/index?navIndex=3"
						}, {
							"title": this.$t("SafeguardTask"),
							"title_initial": "S",
							"name": "Insurance",
							"icon": this.$mAssetsPath.guarantee,
							"group": "task",
							"url": "/pages/application/works/" + mConstDataConfig.airportSignage +
								"/index?navIndex=1"
						}, {
							"title": this.$t('MaintainTask'),
							"title_initial": "Y",
							"name": "Employees",
							"icon": this.$mAssetsPath.repair,
							"group": "task",
							"url": "/pages/application/works/" + mConstDataConfig.airportSignage +
								"/index?navIndex=5"
						}]
					}, {
						"showModel": false,
						"title": "学习园地",
						"id": "learn",
						"menuName": "应用",
						"menuNameItem": "学习",
						"menu": 5,
						"meauI": 10,
						"list": [{
							"menu": 29,
							"showItem": false,
							"title": "案例维修",
							"icon": this.$mAssetsPath.knowledgeBase,
							"name": "News",
							"group": "learn",
							"menuName": "案例维修",
							"url": "/pages/center/learn/repairCase/repairCase"
						}, {

							"menu": 30,
							"showItem": false,
							"title": "考试",
							"icon": this.$mAssetsPath.exam,
							"name": "News",
							"group": "learn",
							"menuName": "考试",
							"url": "/pages/center/learn/exam/exam"
						}, {

							"menu": 31,
							"showItem": false,
							"title": "问卷调查",
							"icon": this.$mAssetsPath.questionnaire,
							"name": "News",
							"group": "learn",
							"menuName": "问卷",
							"url": "/pages/center/learn/questionnaire/questionnaire"
						}]
					},
					{
						"showModel": false,
						"title": "设备档案",
						"id": "archives",
						"menuName": "应用",
						"menuNameItem": "档案",
						"menu": 5,
						"meauI": 11,
						"list": [{

							"menu": 32,
							"showItem": false,
							"title": "维修指引",
							"icon": this.$mAssetsPath.guide,
							"name": "News",
							"menuName": "维修指引",
							"url": "/pages/center/archives/repair/repair"
						}, {

							"menu": 33,
							"showItem": false,
							"title": "保养标准",
							"icon": this.$mAssetsPath.stader,
							"name": "News",
							"group": "learn",
							"menuName": "保养标准",
							"url": "/pages/center/archives/standard/standard1"
						}, ]
					},
					{
						"showModel": false,
						"title": "智慧运维",
						"id": "archives",
						"menuName": "应用",
						"menuNameItem": "智慧运维",
						"menu": 5,
						"meauI": 34,
						"list": [{
							"menu": 35,
							"showItem": false,
							"title": "专项检查",
							"menuName": "专项检查",
							"icon": this.$mAssetsPath.specialInspect,
							"name": "News",
							"group": "learn",
							"url": "/pages/center/operation/specialInspection/specialInspection"
						}, {

							"menu": 36,
							"showItem": false,
							"title": "其他工作",
							"icon": this.$mAssetsPath.otherWork,
							"name": "News",
							"group": "learn",
							"menuName": "其他工作",
							"url": "/pages/center/operation/otherWork/otherWork"
						}, {
							"menu": 37,
							"showItem": false,
							"title": "交接班记录",
							"icon": this.$mAssetsPath.changeShifts,
							"name": "News",
							"group": "learn",
							"menuName": "交接班记录",
							"url": "/pages/center/operation/changeShifts/changeShifts"
						}]
					}
				],

处理部分:

javascript 复制代码
//获取当前用户对应的菜单 --------开始--------------
			//内部操作是根据完整的菜单列表
			getRouters().then(res => {
				if (res.ok()) {
					console.log(res)
					//声明当前菜单列表
					let meau = []
					//遍历返回的菜单列表获得id列表
					let l = res.data.length
					for (let i = 0; i < l; i++) {
						meau.push(res.data[i].id)
					}
					console.log("后端返回的用户菜单:" + meau)
					//遍历本地静态列表确定是否显示
					let l1 = this.applicationList.length
					for (let i = 0; i < l1; i++) {
						//判断当前模块是否要显示
						// console.log(this.applicationList[i].menu)
						if (meau.indexOf(this.applicationList[i].menu) != -1) {
							//现阶段任务是特殊的,先分开判断
							if (this.applicationList[i].menu != 4 && this.applicationList[i].menu != 5) {
								this.applicationList[i].showModel = true
								//如果显示当前模块,获取当前模块要显示的id列表
								let itemList = []
								let itemLen = res.data[meau.indexOf(this.applicationList[i].menu)].children.length
								//获取二级列表
								for (let p = 0; p < itemLen; p++) {
									itemList.push(res.data[meau.indexOf(this.applicationList[i].menu)].children[p]
										.id)
								}
								//遍历对应的静态列表判断当前页面是否显示
								let itemLen2 = this.applicationList[i].list.length
								for (let q = 0; q < itemLen2; q++) {
									if (itemList.indexOf(this.applicationList[i].list[q].menu) != -1) {
										this.applicationList[i].list[q].showItem = true
									}
								}
							} else if (this.applicationList[i].menu == 5) {
								//应用模块也是特殊化处理
								//先遍历children看有没有现实的,并作为左侧题目,再遍历children的children显示内部的二级页面
								//后端返回的应用模块子模块数
								console.log("进入应用列表")
								let centerChildrenLength = res.data[meau.indexOf(this.applicationList[i].menu)]
									.children.length
								console.log("子模块列表长度" + centerChildrenLength)
								//遍历子模块,如果有就显示
								for (let a = 0; a < centerChildrenLength; a++) {
									console.log(res.data[meau.indexOf(this.applicationList[i].menu)].children[a]
										.id)
									if (res.data[meau.indexOf(this.applicationList[i].menu)].children[a].id == this
										.applicationList[i].meauI) {
										this.applicationList[i].showModel = true
										//再遍历应用子模块中的子列表判断具体功能是否显示
										let smallLength = (res.data[meau.indexOf(this.applicationList[i].menu)]
											.children[a].children || []).length
										console.log(smallLength + "=========")
										if (smallLength > 0) {
											//把对应的id存进去
											let centerMeau = []
											for (let b = 0; b < smallLength; b++) {
												centerMeau.push(res.data[meau.indexOf(this.applicationList[i]
														.menu)]
													.children[a].children[b].id)
											}
											//看本地的有没有符合的,符合就显示
											let itemLen3 = this.applicationList[i].list.length
											console.log(itemLen3)
											for (let f = 0; f < itemLen3; f++) {
												console.log(centerMeau)
												// console.log(centerMeau.indexOf(this.applicationList[i].list[f].menu)
												if (centerMeau.indexOf(this.applicationList[i].list[f].menu) != -
													1) {
													console.log("有啦")
													this.applicationList[i].list[f].showItem = true

												}
											}
										} else {

										}


									}
								}
							} else { //TODO 任务先根据角色显示

								getInfo().then(res1 => {
									let roles = res1.data.roles
									console.log(roles)
									//判断是否显示
									if (roles.indexOf('super_admin') != -1) {
										this.applicationList[i].showModel = true
										let itemLen2 = this.applicationList[i].list.length
										for (let q = 0; q < itemLen2; q++) {
											this.applicationList[i].list[q].showItem = true
										}
									} else {
										if (roles.indexOf('MAINT_OPERATOR') != -1) {
											console.log(roles.indexOf('MAINT_OPERATOR'))
											this.applicationList[i].showModel = true
											this.applicationList[i].list[0].showItem = true
										}
										if (roles.indexOf('OPERATOR_PBB') != -1) {
											console.log("不是操作员")
											// console.log(roles.indexOf('OPERATOR_PBB'))
											this.applicationList[i].showModel = true
											this.applicationList[i].list[1].showItem = true
										}
										if (roles.indexOf('OPERATOR_APU') != -1) {
											// console.log(roles.indexOf('OPERATOR_APU'))
											console.log("不是操作员")
											this.applicationList[i].showModel = true
											this.applicationList[i].list[1].showItem = true
										}
										if (roles.indexOf('MAINT_OPERATOR') != -1) {
											console.log(roles.indexOf('MAINT_OPERATOR'))
											this.applicationList[i].showModel = true
											this.applicationList[i].list[2].showItem = true
										}
									}
									/**
									 * 判断跳转参数
									1 遍历this.applicationList[i]
									2 不是操作员,保障不显示,不用改
									 */

									if (roles.indexOf('OPERATOR_APU') == -1 && roles.indexOf(
											'OPERATOR_PBB') == -1) {
										//判断是不是维修人员
										//是维修人员 维修变成0,保养变成2
										if (roles.indexOf('MAINT_OPERATOR') != -1) {
											this.taskIndex1 = 0
											this.applicationList[i].list[0].url =
												"/pages/application/works/index?navIndex=0"
											this.applicationList[i].list[2].url =
												"/pages/application/works/index?navIndex=2"
										} else { //不是维修人员,按理说不显示


										}

									} else { //只要是操作员,必有保障,只要跳0即可 原本就是0不用变
										//判断还是不是维修人员
										//是的话也是按顺序往上加,不用变,不是的话也不用变QAQ
										if (roles.indexOf('MAINT_OPERATOR') != -1) {} else {}
									}
								})

							}
						}
					}


				}
			})
			获取当前用户对应的菜单 --------结束--------------

方法2 :根据路由中的汉字名称判断 优:不用担心id不同菜单紊乱的问题 缺:跟id一样,判断逻辑不复杂但是冗长

处理代码:

javascript 复制代码
	getRouters().then(res => {
				if (res.ok()) {
					//声明返回的菜单名列表
					let nameMeau = []
					let allMeau = res.data
					//遍历返回的菜单列表获得id列表
					let l = (res.data || []).length
					for (let i = 0; i < l; i++) {
						nameMeau.push(res.data[i].menuName)
					}
					//遍历本地静态列表确定是否显示
					let staticMeauLength = this.applicationList.length
					for (let i in this.applicationList) {
						//判断当前模块是否要显示
						if (nameMeau.indexOf(this.applicationList[i].menuName) != -1) {
							let modeName = this.applicationList[i].menuName
							console.log(modeName)
							//任务,应用要特殊化
							if(modeName == "任务"){
								this.applicationList[i].menuName
							}else if(modeName == "应用"){
							let index = nameMeau.indexOf(this.applicationList[i].menuName)			
							//判断应用有没有二级列表
							if(allMeau[index].children != null){
								//声明返回二级菜单名称列表
								let titleList = []
								// console.log(allMeau[index].children)
								for(let p in allMeau[index].children){
									titleList.push(allMeau[index].children[p].menuName)
									if(titleList.includes(this.applicationList[i].menuNameItem)){
										//将应用二级标题展示
										this.applicationList[i].showModel = true
										let titleIndex = titleList.indexOf(this.applicationList[i].menuNameItem)
										//获取要展示的功能的列表的长度
										let itemLength = (allMeau[index].children[titleIndex].children||[]).length
										if(itemLength > 0){
											//声明要展示的功能的名称列表
											let itemNameList = []
											for(let q in allMeau[index].children[titleIndex].children){
												itemNameList.push(allMeau[index].children[titleIndex].children[q].menuName)
											}
											// 遍历叶子节点将功能显示
											for(let m in this.applicationList[i].list){
												if(itemNameList.includes(this.applicationList[i].list[m].menuName)){
													console.log(allMeau[index].children[titleIndex].children)	
													this.applicationList[i].list[m].showItem = true
												}
											}
										}

									}
								}

								//判断
								// console.log(itemList)
								// for(let q in this.applicationList[i].list){
								// 	console.log(itemList)
								// 	console.log(itemList.indexOf("问卷"))
								// 	if(itemList.indexOf(this.applicationList[i].list[q].menuName) != -1){
								// 		console.log("显示"+this.applicationList[i].list[q].menuName)
								// 		this.applicationList[i].list[q].showItem = true
								// 	}
								// }
							}
							console.log(allMeau[index])
							// res.data[meau.indexOf(this.applicationList[i].menu)].children[a]
							// 								.id
							}else{

							}
						}
					}
				}
			})

方法三:将静态路由由树状改为平面数组,数组内对象添加父id,整体还是通过名称来判断,同伙静态路由的父id来实现应用模块的特殊化需求,遍历路由后将数组重新组成树结构

javascript 复制代码
//遍历菜单树
			dfsMeauTree(meauList) {
				let that = this
				if(meauList.visible == 1){
				that.nameList.push(meauList.menuName)}
				if (meauList.children) {
					meauList.children.forEach(child => this.dfsMeauTree(child));
				}
			},
			buildTree(arr, parentId = null) {
				let result = [];
				let temp = arr.filter(item => item.parentId === parentId);
				temp.forEach(item => {
					//对于每个节点,递归调用buildTree函数来构建其子树,并将结果赋值给item.children。
					let children = this.buildTree(arr, item.id);
					if (children.length) {
						item.children = children;
					}
					result.push(item);
				});
				//将当前节点添加到结果数组中。最终,返回结果数组作为树的根节点。
				return result;
			},
			detailMeau() {
				console.log("处理菜单")
				let that = this
				let aasd = []
				//获取要展示的功能名称列表
				getRouters().then(res => {
					let currentName = []
					for (let i in res.data) {
						that.dfsMeauTree(res.data[i])
					}
					console.log(that.nameList)
					for (let i in that.nameList) {
						currentName.push(that.nameList[i])
					}
					//遍历本地静态数组
					for (let i in this.applicationList) {
						if (currentName.includes(this.applicationList[i].menuName)) {
							console.log(this.applicationList[i].menuName)
							this.applicationList[i].showItem = true
							this.applicationList[i].showModel = true
						}
						//对任务模块的进行特殊处理
						getInfo().then(res1 => {
							let roles = res1.data.roles
							if (this.applicationList[i].parentId == "TaskManagement") {
								for (let p in this.applicationList[i].role) {
									// console.log("遍历任务选项中角色的循环======"+p)
									if (roles.indexOf(this.applicationList[i].role[p]) != -1 || roles.indexOf(
											'super_admin') != -1) {
										this.applicationList[i].showItem = true
										// break;
									}else{
										this.applicationList[i].showItem = false
									}
								}
							}
						})
					}


					//将数组转换成树形结构
					let meauTree = that.buildTree(this.applicationList)
					this.meauTree = meauTree
				})
			}

		}
相关推荐
崔庆才丨静觅8 分钟前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60611 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了1 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅1 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅1 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅2 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment2 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅2 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊2 小时前
jwt介绍
前端
爱敲代码的小鱼2 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax