# admin_web **Repository Path**: jxqmmty/admin_web ## Basic Information - **Project Name**: admin_web - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-04-21 - **Last Updated**: 2025-11-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 图片预览 ### PC端 #### 登录页面 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694085463479-63c2ea52-2900-457b-a3f9-5b7c72c48cb3.png#averageHue=%23e2c899&clientId=ufbd4c760-846c-4&from=paste&height=687&id=UHuvk&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=111233&status=done&style=none&taskId=u9f985d88-d0ea-4794-b1b8-a36ebc00710&title=&width=1280) #### 注册页面 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694085502246-a77e95ee-7da2-45a3-815e-525b6bba0c25.png#averageHue=%23dfaf38&clientId=ufbd4c760-846c-4&from=paste&height=687&id=WzNFX&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=50580&status=done&style=none&taskId=ubc44c73f-2b64-46bf-9369-85a7424d6f3&title=&width=1280) #### 信息提示页 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694085909609-2ea662ee-9630-4bb1-b7fa-9882b4ba4b2d.png#averageHue=%23f8f7f7&clientId=ufbd4c760-846c-4&from=paste&height=687&id=u97dcf8c7&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=79717&status=done&style=none&taskId=u0560a4f3-755b-4ec5-81e6-4b52dcb6395&title=&width=1280) #### 权限管理页 ##### 员工列表 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694085972786-06f52999-13b1-4e8f-b6c8-f8b3b8e2ab38.png#averageHue=%23fbfafa&clientId=ufbd4c760-846c-4&from=paste&height=687&id=udb6974d5&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=126587&status=done&style=none&taskId=u7192295d-74f9-4d55-9990-8c7a1893b1f&title=&width=1280)
![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694087025847-0afec9c7-2f4e-46f5-8c09-a58939bb2be0.png#averageHue=%23949393&clientId=ufbd4c760-846c-4&from=paste&height=687&id=uf0aca3dc&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=118715&status=done&style=none&taskId=u3186b5e8-ac01-472b-a099-ca1d81a5891&title=&width=1280) ##### 角色列表 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694086003133-b0232473-b360-4805-aacc-481e0cddf71e.png#averageHue=%23fdfcfc&clientId=ufbd4c760-846c-4&from=paste&height=687&id=ucfcf2054&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=120200&status=done&style=none&taskId=ua958eda5-cbdf-4b47-9e8b-2a9f6955554&title=&width=1280)
![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694087045886-c7259fe2-d9df-4cd1-8a6f-5315157299d9.png#averageHue=%23b7b7b7&clientId=ufbd4c760-846c-4&from=paste&height=687&id=u0b6413ac&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=129736&status=done&style=none&taskId=ufcf2d139-9bbd-4748-9c01-add7bccf709&title=&width=1280) ##### 权限列表 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694086042185-050f4279-814b-4731-bf51-ea1464ef0c35.png#averageHue=%23fdfbfa&clientId=ufbd4c760-846c-4&from=paste&height=687&id=u2028adcb&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=132902&status=done&style=none&taskId=u33e44c7f-1001-44c6-94e1-5d3c53c9c89&title=&width=1280)
![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694087073581-8de4a173-2659-497b-94b1-4a583123bade.png#averageHue=%23a5a3a3&clientId=ufbd4c760-846c-4&from=paste&height=687&id=u8fbb5786&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=137721&status=done&style=none&taskId=u0f99e011-f3e8-4146-8326-1be49f81fb1&title=&width=1280) #### 导航栏折叠 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694087154062-f3888beb-5bf2-4466-bc27-5a84ef78d8eb.png#averageHue=%23fdfbfb&clientId=ufbd4c760-846c-4&from=paste&height=687&id=u826f55e7&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=113489&status=done&style=none&taskId=ua1ed8d86-e580-431d-a030-0f822fb1b81&title=&width=1280) ### 移动端 #### 登录页面 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694085670782-fb58c9f9-2ad5-4340-a159-5ab3438330e2.png#averageHue=%23e2efd6&clientId=ufbd4c760-846c-4&from=paste&height=501&id=jLZoy&originHeight=752&originWidth=422&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=35115&status=done&style=none&taskId=uc17a43f6-dfbd-4c76-aaae-a30bed6eb8a&title=&width=281.3333333333333) #### 注册页面 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694085616719-1702b404-908b-47dd-ac50-b1e0b0334ed1.png#averageHue=%23e3e1bc&clientId=ufbd4c760-846c-4&from=paste&height=502&id=HO6js&originHeight=753&originWidth=423&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=18304&status=done&style=none&taskId=ueec2f3da-93fb-494a-b038-4fc3072517c&title=&width=282) #### 信息提示页 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694086232217-3ecabeae-1d59-4741-afde-f1167ad5d707.png#averageHue=%23f6f6f6&clientId=ufbd4c760-846c-4&from=paste&height=498&id=u01bec3d9&originHeight=747&originWidth=421&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=27270&status=done&style=none&taskId=u3c99b2a0-c43f-4bb6-8235-c92e943c39a&title=&width=280.6666666666667) #### 权限管理页 ##### 员工列表 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694086411107-9acb25a4-9d47-47a2-9b6f-4882d9128e97.png#averageHue=%23fbfbfa&clientId=ufbd4c760-846c-4&from=paste&height=501&id=Sp08x&originHeight=751&originWidth=421&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=43978&status=done&style=none&taskId=u4bd5e2e2-91c8-4bb0-9a33-868fcfed307&title=&width=280.6666666666667)
![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694086650079-626b9e5c-e8ec-4aa3-9d49-d016f8f783ff.png#averageHue=%23fefefe&clientId=ufbd4c760-846c-4&from=paste&height=501&id=uf6409ac3&originHeight=751&originWidth=421&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=11091&status=done&style=none&taskId=u45eae651-2ac6-423a-a9f5-1cd271cf367&title=&width=280.6666666666667) ##### 角色列表 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694086469747-7077b565-daae-49f8-ab08-095e7454590e.png#averageHue=%23fdfdfd&clientId=ufbd4c760-846c-4&from=paste&height=501&id=XJyEb&originHeight=751&originWidth=421&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=39189&status=done&style=none&taskId=uce64dd7a-5781-49ae-85a2-ed3b2d04ce1&title=&width=280.6666666666667)
![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694086601320-19ec92af-6068-4c83-966f-e1535c108fec.png#averageHue=%23fefefe&clientId=ufbd4c760-846c-4&from=paste&height=501&id=ueec4dbac&originHeight=751&originWidth=421&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=31322&status=done&style=none&taskId=u5cfc60be-044c-4d84-9447-2efbfe3e635&title=&width=280.6666666666667) ##### 权限列表 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694086528683-2235c3b1-dcc0-448a-9ffa-62f843235eef.png#averageHue=%23fdf7f6&clientId=ufbd4c760-846c-4&from=paste&height=501&id=u29b21df9&originHeight=751&originWidth=421&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=47573&status=done&style=none&taskId=u52686392-bbc0-4d68-b985-22f4bcffc39&title=&width=280.6666666666667)
![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694086546625-1582d17a-35c6-41c1-a0d2-ff647781f2de.png#averageHue=%23fefefe&clientId=ufbd4c760-846c-4&from=paste&height=501&id=ud6273865&originHeight=751&originWidth=421&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=17423&status=done&style=none&taskId=u9266926c-f4ff-47c4-a0ca-324c45e7fa6&title=&width=280.6666666666667) #### 导航栏展开 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694086725456-3cfe3835-069f-4ce0-b9f2-49aa8fa8d702.png#averageHue=%23faf7f7&clientId=ufbd4c760-846c-4&from=paste&height=501&id=u0c410e5c&originHeight=751&originWidth=421&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=43022&status=done&style=none&taskId=u129c2626-ad82-40c9-8758-19351ce393c&title=&width=280.6666666666667) ### 功能展示 #### 页面搜索 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694086861684-b766dd2c-70d4-4b9a-b2ca-3c5c9a562668.png#averageHue=%23faf7f7&clientId=ufbd4c760-846c-4&from=paste&height=501&id=u01cd6e07&originHeight=751&originWidth=421&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=38635&status=done&style=none&taskId=u02bb6226-8981-4b16-b4ff-4c3531a50ed&title=&width=280.6666666666667) #### 多语言 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694086905531-8859fb05-165d-4fd3-80b2-219cc3e79f53.png#averageHue=%23faf7f7&clientId=ufbd4c760-846c-4&from=paste&height=501&id=u1c3ce9b9&originHeight=751&originWidth=421&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=42832&status=done&style=none&taskId=u02fbfcf3-3f8d-4a86-959f-764405b61b8&title=&width=280.6666666666667) #### 暗夜模式 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694086955762-dc9e6e31-73af-4526-9414-f32295ba817c.png#averageHue=%2360b644&clientId=ufbd4c760-846c-4&from=paste&height=501&id=u0c46c7c7&originHeight=751&originWidth=421&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=37137&status=done&style=none&taskId=u9c00bd78-0421-41ae-a05c-a2e04d049b6&title=&width=280.6666666666667) ## 在线体验地址 [vue3c-admin在线体验地址](http://vue3-admin.webproject.maofu123.top/) --- # 技术栈说明 | **依赖名** | **应用于哪些分支** | **官网** | | --- | --- | --- | | vue3 | all | [https://cn.vuejs.org/guide/introduction.html](https://cn.vuejs.org/guide/introduction.html) | | vue-cli | all | [Vue CLI](https://cli.vuejs.org/zh/) | | element-plus | all | [快速开始 | Element Plus](https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E5%AE%8C%E6%95%B4%E5%BC%95%E5%85%A5) | | axios | all | [Axios 中文文档 | Axios 中文网 | Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js](https://www.axios-http.cn/) | | vuex 4 | all | [Vuex 是什么? | Vuex](https://vuex.vuejs.org/zh/) | | vue router | all | [Vue Router](https://router.vuejs.org/zh/) | | mock.js
(模拟api接口服务器数据) | 除了包含mockjs-pro的分支 | [Getting Started](https://github.com/nuysoft/Mock/wiki/Getting-Started) | | mockjs-pro
(
该项目 fork 自 mockjs,修复了 mockjs 中 Mock.mock()不能使用 Promise 和 async 异步函数的 bug。
) | version-RBAC_page
version-RBAC_page-S-T
version-RBAC_page-S-T-i18n | [mockjs-pro](https://www.npmjs.com/package/mockjs-pro) | | dexie
(用于操作IndexedDB数据库) | version-RBAC_page
version-RBAC_page-S-T
version-RBAC_page-S-T-i18n | [Dexie.js - Minimalistic IndexedDB Wrapper](https://dexie.org/) | | md5
(加密密码传输到服务器) | all | [md5](https://www.npmjs.com/package/md5) | | screenfull | all | [screenfull](https://www.npmjs.com/package/screenfull) | | vue-i18n | version-xxx-i18n | [Vue I18n | Vue I18n](https://vue-i18n.intlify.dev/) | | day.js | version-RBAC_page
version-RBAC_page-S-T
version-RBAC_page-S-T-i18n | [Day.js · 2kB JavaScript date utility library](https://day.js.org/en/) | | xlsx | version-RBAC_page
version-RBAC_page-S-T
version-RBAC_page-S-T-i18n | [xlsx](https://www.npmjs.com/package/xlsx) | | file-saver
(文件下载) | version-RBAC_page
version-RBAC_page-S-T
version-RBAC_page-S-T-i18n | [file-saver](https://www.npmjs.com/package/file-saver) | | fuse.js(模糊搜索) | version-xxx-search
version-xxx-S-T | [fuse.js](https://www.npmjs.com/package/fuse.js) | --- # 选择合适你的版本(分支) | 分组 | **分支名称** | **包含功能** | **页面** | | --- | --- | --- | --- | | 1
基础本版 | version-base | 路由渲染菜单栏
明暗切换
全屏 | ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694167422446-b78fa53e-0f02-4485-8a10-0a20bfe1c410.png#averageHue=%23f6f5f5&clientId=uc0d96bf5-b75f-4&from=paste&height=687&id=D8XUV&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=71556&status=done&style=none&taskId=u4c80b3cf-9a6f-4fc4-a31b-0a7c6eaa001&title=&width=1280) | | | version-base-i18n | 路由渲染菜单栏
明暗切换
全屏
+i18n国际化 | | | | | | | | 2
实现页面模糊搜索 | version-seach | 路由渲染菜单栏
明暗切换
全屏
+页面模糊搜索 | ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694168443680-3084f1d9-f5f5-405e-a22c-262d0f7a1d3b.png#averageHue=%23f6f5f5&clientId=uc0d96bf5-b75f-4&from=paste&height=687&id=uc5cd6648&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=74288&status=done&style=none&taskId=u59d6e0cd-3d41-47bc-916f-61eab733c32&title=&width=1280) | | | version-search-i18n | 路由渲染菜单栏
明暗切换
全屏
+页面模糊搜索
+i18n国际化 | | | | | | | | 3
实现tags标签栏 | version-tagsView | 路由渲染菜单栏
明暗切换
全屏
+tags标签栏 | ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694169078437-c747d417-1855-4ed7-bd78-759e8cac37b5.png#averageHue=%23f7f6f6&clientId=uc0d96bf5-b75f-4&from=paste&height=687&id=u7823490b&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=75013&status=done&style=none&taskId=u6557d18e-0f25-4961-96e4-3e1ec34557a&title=&width=1280) | | | version-tagsView-i18n | 路由渲染菜单栏
明暗切换
全屏
+tags标签栏
+i18n国际化 | | | | | | | | 4
同时集成 页面搜索+tags标签栏 | version-search-tagsView | 路由渲染菜单栏
明暗切换
全屏
+页面模糊搜索
+tags标签栏 | ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694170384659-e1ce8828-937e-417d-be89-07f73ce26464.png#averageHue=%23f7f6f6&clientId=uc0d96bf5-b75f-4&from=paste&height=687&id=u616715e7&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=89018&status=done&style=none&taskId=ufabe8b8a-b1e1-4ca2-a3a8-707193195cf&title=&width=1280) | | | version-search-tagsView-i18n | 路由渲染菜单栏
明暗切换
全屏
+页面模糊搜索
+tags标签栏
+i18n国际化 | | | | | | | | 5
实现RBAC访问控制 | version-RBAC | 路由渲染菜单栏
明暗切换
全屏
+在`src\\store\\modules\\routes.js`中实现了根据用户权限信息动态添加路由 | ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694169302900-356d28a3-dc52-4660-b8c9-3ed40be1a27b.png#averageHue=%23f6f5f5&clientId=uc0d96bf5-b75f-4&from=paste&height=687&id=u849a00a3&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=74456&status=done&style=none&taskId=u9b62703f-a5d6-44d8-aeb8-e7abcd567b4&title=&width=1280) | | | version-RBAC-i18n | 路由渲染菜单栏
明暗切换
全屏
+在`src\\store\\modules\\routes.js`中实现了根据用户权限信息动态添加路由
+i18n国际化 | | | | version-RBAC_page | 路由渲染菜单栏
明暗切换
全屏
+实现RBAC管理页面 | ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694169930193-c96ac211-e8a5-47c6-9075-09777f3861a6.png#averageHue=%23fdfafa&clientId=uc0d96bf5-b75f-4&from=paste&height=687&id=dikuT&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=125272&status=done&style=none&taskId=u4840b196-ae1f-4838-b2b2-a31a6c490c3&title=&width=1280) | | | | | | | | | | | | | | | 6
集成 页面搜索+tags标签栏+RBAC访问控制 | version-RBAC_page-S-T | 路由渲染菜单栏
明暗切换
全屏
+页面模糊搜索
+tags标签栏
+实现RBAC管理页面 | ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694170067313-f3b8918b-5d4e-4ffa-885b-a41c0de428a0.png#averageHue=%23fdfbfa&clientId=uc0d96bf5-b75f-4&from=paste&height=687&id=ZheFe&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=129100&status=done&style=none&taskId=u753727f3-ed13-4776-9be5-9defd258170&title=&width=1280) | | | version-RBAC_page-S-T-i18n | 路由渲染菜单栏
明暗切换
全屏
+页面模糊搜索
+tags标签栏
+实现RBAC管理页面
+i18n国际化 | | --- # 快速开始 ## 克隆该项目 例如 ```javascript git clone https://gitee.com/tmaofu/back_office_management.git ``` ## 安装依赖 进入项目目录,打开终端
先安装yarn包管理器 ```javascript npm install -g yarn ``` 再安装项目依赖 ```javascript yarn install ``` ## 启动项目 ```javascript npm start ``` ## 打包输出 ```javascript npm run build ``` ## 使用 eslint 代码规范校验 请根据需要修改`.eslintrc.js`配置文件。 ## 使用 git cz 提交本地仓库 全局安装Commitizen ```javascript npm install -g commitizen@4.2.4 ``` 修改文件代码
添加到暂存区: ```javascript git add . ``` 使用` git cz` 代替 `git commit` : ```javascript git cz ``` ## 在合适的时候移除mockjs 当你已经根据api接口文档,完成了一部分api接口的时候,你想要使用自己的api接口进行测试,那么这时候你就可以删除mock的接口。
例如你已经完成了注册接口,那么你就可以删除以下mock的接口:
![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694173208020-4888f2a8-351a-44d9-83ac-32b2c7b03210.png#averageHue=%23ededec&clientId=uc0d96bf5-b75f-4&from=paste&height=687&id=ucabf2188&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=248610&status=done&style=none&taskId=u3153f89f-d2eb-405b-abe7-af1faba63bd&title=&width=1280)
当你已经完成了所有接口时,你可以删除整个mock 文件夹,并在main.js中解除引入:
![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694173342537-6429aa95-3fc3-498f-9e96-5e499ae7156c.png#averageHue=%23edeceb&clientId=uc0d96bf5-b75f-4&from=paste&height=687&id=ufb881c5a&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=306528&status=done&style=none&taskId=u6ac71443-2380-405b-80e8-07acc1ecfd3&title=&width=1280) --- # 目录结构说明 ## 顶层目录概览 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694090868925-f419b79a-95d4-4f69-9d40-1571d36adb7a.png#averageHue=%23f0eeed&clientId=ufbd4c760-846c-4&from=paste&height=611&id=u41776fab&originHeight=917&originWidth=412&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=56672&status=done&style=none&taskId=u288c38d8-3b38-4a5e-9bab-414624c4869&title=&width=274.6666666666667)
dist:打包后的文件
node_modules:npm包
public:静态资源,不会被压缩
src: - api:api接口统一管理 - assets:存放所需的静态资源 - components:存放公用组件 - constant:存放常量,如一些键值 - directives:存放自定义vue指令 - filter:存放过滤器 - i18n:实现国际化 - layout:实现layout布局页面 - mock:拦截api请求,放回mock的数据 - router:app路由 - store:状态仓库 - style:存放通用样式文件 - utility:存放工具性质的文件 - validator:存放合法性校验的文件 - views:存放路由页面 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694091041067-bbf402b6-292e-4e9f-97f6-34666902d257.png#averageHue=%23f0eeed&clientId=ufbd4c760-846c-4&from=paste&height=605&id=w6TGz&originHeight=908&originWidth=412&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=47661&status=done&style=none&taskId=u416c9d6b-99dd-4ce5-b8a8-9e856b99628&title=&width=274.6666666666667) - App.vue:根组件 - main.js:入口文件 - settings.js:该应用的一些配置,可根据需要修改 ## src目录详解 ### api:api接口统一管理 ```javascript ├─api │ permission-manage.js //权限列表管理api │ read.md │ role-manage.js //角色列表管理api │ sys.js │ user-manage.js //员工列表管理api ``` ### assets:存放所需的静态资源 ```javascript ├─assets │ │ logo.png │ │ │ ├─icon │ │ │ index.js //使webpack打包svg图标 │ │ │ │ │ └─svg //存放svg图标 │ │ │ ├─img //存放图片 │ │ │ └─scss │ reset.scss //清除浏览器默认样式 ``` ### components:存放公用组件 #### Breadcrumb ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694093875034-6a6c4636-ad6f-4965-9c77-c7614ee630b8.png#averageHue=%23f7f7f7&clientId=ufbd4c760-846c-4&from=paste&height=687&id=u254dd2ce&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=84209&status=done&style=none&taskId=ue6b3fff8-45d5-493a-9953-364cd7abdd5&title=&width=1280) #### LanguageSwitch ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694093905409-e8b853ed-bca2-4902-bc22-5b93ea04119f.png#averageHue=%23f7f7f7&clientId=ufbd4c760-846c-4&from=paste&height=687&id=u45808a48&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=87527&status=done&style=none&taskId=u006232dc-84ea-4e20-9a33-f46d9b3242f&title=&width=1280) #### LightDarkSwitch ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694093935152-d56beee3-40c7-4a0d-bae2-1bb4b8dc322b.png#averageHue=%23f7f7f7&clientId=ufbd4c760-846c-4&from=paste&height=687&id=ub32280fd&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=85731&status=done&style=none&taskId=u291215b9-59e9-47a0-b36c-33a7e71929d&title=&width=1280) #### PageSearch ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694093953188-677e598b-6da9-4b8f-ac5f-ffe648c8f4d3.png#averageHue=%23f7f7f7&clientId=ufbd4c760-846c-4&from=paste&height=687&id=u8e33447a&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=84685&status=done&style=none&taskId=u1254edaa-9dd1-41d0-8c22-4b3c306321f&title=&width=1280) #### ScreenFull ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694093975109-88f33f86-2b4f-4322-a517-71016bd5d5c2.png#averageHue=%23f7f7f7&clientId=ufbd4c760-846c-4&from=paste&height=687&id=u622ad415&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=85671&status=done&style=none&taskId=u74315deb-8e83-49e4-99a7-33e34add4a0&title=&width=1280) #### SvgIcon ```markdown 使用方式: 使用icon 这个props进行传参,可接收: 1.图标字体类名 2.svg的url 3.'my-'+本地src/assets/icon/svg中的svg名称,例如:icon="my-login" ``` ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694094061683-98718179-fa27-4b18-83ed-097f5be71044.png#averageHue=%23f7f7f7&clientId=ufbd4c760-846c-4&from=paste&height=687&id=ubc11deb8&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=85318&status=done&style=none&taskId=ue926c910-9bf3-4be1-8858-291ed636e23&title=&width=1280) #### TagsView ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694094167516-5583794b-c3f3-4290-acea-c9e5e7e30aa9.png#averageHue=%23f7f7f7&clientId=ufbd4c760-846c-4&from=paste&height=687&id=uf477d275&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=84934&status=done&style=none&taskId=u17013f0c-af82-4777-967f-3efd651945f&title=&width=1280) #### UploadExcel ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694094314342-c1a9dc2a-55d0-4268-b8c8-f64e92241138.png#averageHue=%23acacac&clientId=ufbd4c760-846c-4&from=paste&height=687&id=u4be65dc9&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=129592&status=done&style=none&taskId=udfebf118-3184-4a99-9eb8-862c01ff683&title=&width=1280) ### constant:存放常量,如一些键值 ```javascript export const TOKEN = 'token' export const USERLANGUAGE = 'user-language' ``` ### directives:存放自定义vue指令 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694094450359-c005d77f-cae0-485f-8279-d08fe2b1dc11.png#averageHue=%23efeeee&clientId=ufbd4c760-846c-4&from=paste&height=687&id=ucb2aa760&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=155486&status=done&style=none&taskId=ud59b6ce5-64d9-4292-92d7-5089f69f0fa&title=&width=1280) ### filter:存放过滤器 ```javascript import dayjs from 'dayjs' export function dateFilter(val, format = 'YYYY-MM-DD') { if (!isNaN(val)) { val = parseInt(val) } return dayjs(val).format(format) } export default function useFilter(vueApp) { vueApp.config.globalProperties.$filters = { dateFilter } } ``` ### i18n:实现国际化 ### layout:实现layout布局页面 #### AppMain ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694094970801-51e4d7af-ce85-42db-b337-533c9cc5bd6e.png#averageHue=%23f7f7f7&clientId=ufbd4c760-846c-4&from=paste&height=687&id=u83efd20d&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=85550&status=done&style=none&taskId=u38543145-9543-4b5f-8d47-39ab5684781&title=&width=1280) #### NavBar ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694094996859-bbaba0e1-2339-4008-8313-fa381a4cedc6.png#averageHue=%23f7f7f7&clientId=ufbd4c760-846c-4&from=paste&height=687&id=u119ab946&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=85667&status=done&style=none&taskId=u8f8f1260-9beb-4c4e-b21a-a99bcdd7a61&title=&width=1280) #### SideBar ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694095029525-0fcd5eed-8381-4341-8cdc-2f97d6a74788.png#averageHue=%23f7f6f6&clientId=ufbd4c760-846c-4&from=paste&height=687&id=ucffec42d&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=90858&status=done&style=none&taskId=u32580294-35e3-4c3c-9502-d40119abb76&title=&width=1280) ##### SidebarItem ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694095136489-5f0a3f3c-9034-4377-a5ce-9a962508da18.png#averageHue=%23f7f6f6&clientId=ufbd4c760-846c-4&from=paste&height=687&id=u7fb1ef31&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=90923&status=done&style=none&taskId=uc1732736-29f0-428e-8588-156164c8686&title=&width=1280) ##### SidebarMenu ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694095159776-6590aca3-93a7-47b6-a9a1-7bc54eb1f2cc.png#averageHue=%23f7f6f6&clientId=ufbd4c760-846c-4&from=paste&height=687&id=ufc68519b&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=91004&status=done&style=none&taskId=u67392043-16a7-43eb-8003-60196e7c1c2&title=&width=1280) ### mock:拦截api请求,反回mock(模拟)的数据 ```javascript ├─mock │ │ index.js //入口文件 │ │ permission-list.js //拦截权限列表相关的api │ │ role-manage.js //拦截角色列表相关的api │ │ sys.js //拦截登录,注册相关的api │ │ user-manage.js //拦截员工列表相关的api │ │ │ └─IndexedDB │ index.js //操作IndexedDB数据库的方法 ``` ### router:app路由 ```javascript ├─router │ index.js //入口文件,配置路由对象 │ permission.js //定义全局前置导航守卫 │ routes.js //定义 公有路由和私有路由 ``` ### store:状态仓库 ```javascript ├─store │ │ getters.js //类似计算属性 │ │ index.js //入口文件 │ │ │ └─modules │ layout.js //关于layout布局页面的状态仓库 │ routes.js //关于路由的状态仓库 │ user.js //关于用户的状态仓库 ``` ### style:存放通用样式文件 ```javascript ├─style │ index.scss │ mobile.scss //一些通用的全局移动端样式 │ theme-dark.scss //暗夜主题样式 │ theme-filter-invert-dark.scss //使用css-filter 实现暗夜主题样式 │ theme-filter-invert-light.scss //使用css-filter 实现明亮主题样式 │ theme-light.scss //明亮主题样式 │ variables-dark.scss //暗夜主题使用的颜色变量 │ variables-light.scss //明亮主题使用的颜色变量 │ variables.scss //一些样式变量 ``` ### utility:存放工具性质的文件 ```javascript ├─utility │ export2Excel.js //导出为excel │ get-screen-info.js //获取屏幕信息,判断是否是移动端 │ request.js //封装axios │ resolveBugs.js //解决element-plus 报错问题 │ set-document-title.js //设置文档标题 │ storage.js //封装localStorage ``` ### validator:存放合法性校验的文件 ```javascript ├─validator │ index.js //包含 登录注册密码校验规则 ``` ### views:存放路由页面 #### 404 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694152445515-21728106-1cbe-4406-883d-756be633efb4.png#averageHue=%23fefefe&clientId=uc900d602-642b-4&from=paste&height=687&id=u6556823c&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=109505&status=done&style=none&taskId=u3b699a0e-5510-4baa-8b67-154748f3cfe&title=&width=1280) #### Acl ##### Menu ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694152530089-1c80cb9c-2488-4177-877c-65d466a5b1aa.png#averageHue=%23f9f8f8&clientId=uc900d602-642b-4&from=paste&height=687&id=uaec58e79&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=101374&status=done&style=none&taskId=u9f161090-64e1-463c-8108-9824c4e1636&title=&width=1280) ##### Role ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694152516361-80def5df-87aa-485f-b5de-c022a4100254.png#averageHue=%23fdfcfc&clientId=uc900d602-642b-4&from=paste&height=687&id=ub7fd8b1d&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=119842&status=done&style=none&taskId=u0fd478ba-2e39-4c23-9d87-d55f4672bec&title=&width=1280) ##### User ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694152498285-787c440e-60e6-4519-8e7c-37724af02ff3.png#averageHue=%23fdfbfb&clientId=uc900d602-642b-4&from=paste&height=687&id=u6567c2e3&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=136511&status=done&style=none&taskId=u8aa9c293-b606-41ed-8882-ad7fb3d41d1&title=&width=1280) #### Client ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694152562116-f652b3bf-b2fd-4e2a-a01c-0301cb0e7711.png#averageHue=%23f7f6f6&clientId=uc900d602-642b-4&from=paste&height=687&id=u95e0bf56&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=70286&status=done&style=none&taskId=u0544eb22-dc15-4ce1-8071-4aba3b00ce6&title=&width=1280) #### Info ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694152574373-3e926a63-6b7d-4e7b-85cf-145d0c7e54e4.png#averageHue=%23f7f7f7&clientId=uc900d602-642b-4&from=paste&height=687&id=u03797c68&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=86670&status=done&style=none&taskId=ub888fc71-23ab-4e48-b602-638c6e63516&title=&width=1280) #### Login ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694152588524-39ebd678-ed4b-4fab-8522-b50ca41669c6.png#averageHue=%23e2c899&clientId=uc900d602-642b-4&from=paste&height=687&id=u03fb71de&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=110195&status=done&style=none&taskId=u8e03fc3a-466e-48bc-a5a0-329607d4955&title=&width=1280) #### Register ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694152598174-c448a57f-2445-4cea-aa61-d7331dff0cd0.png#averageHue=%23dfaf38&clientId=uc900d602-642b-4&from=paste&height=687&id=u630528f7&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=50580&status=done&style=none&taskId=u4568022f-be00-4b34-a2d5-68554fc14dd&title=&width=1280) ### App.vue:根组件 ```javascript ``` ### main.js:入口文件 ### settings.js:该应用的一些配置,可根据需要修改 ```javascript import i18n from '@/i18n' export default { /** * 页面标题 */ pageTile: i18n.$t('src.settings.808362-0'), /** * 侧边栏 */ sideBar: { // sideBarLogo: { // isShow: true, // type: 'text', // 'text'or'img' // value: '后台管理系统' // }, sideBarLogo: { isShow: true, type: 'img', // 'text'or'img' value: '/favicon.ico' }, uniqueOpened: true, // 是否只保持一个子菜单的展开 // 侧边栏宽度 initWidth: 200, // 初始宽度,填写整数,单位是px minDargWidth: 180, // 最小宽度 maxDargWidth: 250, // 最大宽度 mobileCollapseToZero: true // 为移动端页面时,收缩侧边栏宽度到0 }, /** * 顶部导航栏 */ narBarFixed: true, // 是否固定导航条 narBarSeparator: '/' // 面包屑分隔符 } ``` --- # 功能使用指南 ## 根据路由表渲染侧边栏菜单功能 ### 公共路由表 与 私有路由表 路由表的配置在 `src\router\routes.js`中,如果要添加公共路由记录请添加在 `publicRoutes`中,如果要添加私有路由记录请添加在 `privateRoutes`中。 ### 字段说明 ```javascript { path: 'client', name: 'client-management', meta: { title: '客户管理',//会显示为菜单名称 icon: 'my-user'//配置菜单名称左侧的图标,使用自定义SvgIcon组件实现,可选值可以查看SvgIcon组件的说明。 }, component: () => import('@/views/Client') } ``` ### 顶层菜单 | **效果** | **实现方式** | | --- | --- | | ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694153883261-0866e141-62b2-426f-abd0-e60ffce113c5.png#averageHue=%23faf9f9&clientId=uc900d602-642b-4&from=paste&height=611&id=u7fcd717f&originHeight=916&originWidth=299&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=28205&status=done&style=none&taskId=u5d775ac2-b9eb-4298-bf49-1fe7f108946&title=&width=199.33333333333334) | 在 `src\\router\\routes.js`的路由表中添加类似这样一条记录```javascript { path: '/', component: Layout, children: [ { path: 'client', name: 'client-management', meta: { title: i18n.$t('router.routes.817884-1'), icon: 'my-user' }, component: () => import('@/views/Client') } ] }, ``` | ### 子级菜单 | **效果** | **实现方式** | | --- | --- | | ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694154280116-c4e82107-80c4-46cc-a21b-a7d76f02e2c0.png#averageHue=%23fcfbfb&clientId=uc900d602-642b-4&from=paste&height=611&id=u272590e6&originHeight=916&originWidth=298&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=23792&status=done&style=none&taskId=u5e052a1f-ced6-49c1-88c2-f2642104247&title=&width=198.66666666666666) | 在 `src\\router\\routes.js`的路由表中添加类似这样一条记录```javascript { path: '/info', component: Layout, redirect: '/info/info', meta: { title: i18n.$t('router.routes.817884-0'), icon: 'my-info' }, children: [ { path: 'info', name: 'info', component: () => import('@/views/Info'), meta: { title: i18n.$t('router.routes.817884-0'), icon: 'my-info' } } ] }, ``` | ### 多层菜单 | **效果** | **实现方式** | | --- | --- | | ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694153397600-35a9c041-2822-497e-8372-1f32fe145352.png#averageHue=%23fbfbfb&clientId=uc900d602-642b-4&from=paste&height=609&id=uf613c1f6&originHeight=914&originWidth=300&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=27661&status=done&style=none&taskId=u0e7332ce-4248-4e66-ad1f-300174cef7f&title=&width=200) | 在 `src\\router\\routes.js`的路由表中添加类似这样一条记录```javascript { path: '/info', component: Layout, redirect: '/info/info', meta: { title: i18n.$t('router.routes.817884-0'), icon: 'my-info' }, children: [ { path: 'info', name: 'info', component: () => import('@/views/Info'), meta: { title: i18n.$t('router.routes.817884-0'), icon: 'my-info' }, children: [ { path: 'info', name: 'info', component: () => import('@/views/Info'), meta: { title: i18n.$t('router.routes.817884-0'), icon: 'my-info' } } ] } ] }, ``` | ## 页面搜索功能 只要配置了路由表,并且改登录用户拥有该路由记录,就可以进行模糊搜索。具体实现可以查看:`src\components\PageSearch` ## 动态路由表/RBAC功能 首先,请查看`src\router\permission.js`中 路由导航守卫的逻辑 ​```javascript ... // 需要需要权限的页面 else { // 有token,已经登录过 if (store.getters.token) { // 状态仓库中是否有用户信息, // 如果有:代表没有刷新页面|不是重新访问web应用,这时是不需要判断token是否过期的。 if (store.getters.userInfo) { next() // eslint-disable-next-line brace-style } // 没有用户信息,代表用户刚刚访问本站 else { // 用已有的token去获取用户信息,看token是否过期 const ok = await store.dispatch('user/getUserInfo') if (ok) { // 没有过期,放行 // 由于在导航守卫中添加了动态路由,所以需要重定向,而不是直接next() next(to.fullPath) } else { // token过期,需要用户重新登录 // 先清除token,才能跳转登录页 ElMessage.warning(i18n.t('router.permission.808363-0')) store.commit('user/SET_token', '') next('/login') } } // eslint-disable-next-line brace-style } // 无token,没有登录过,需要让用户登录 else { next('/login') } } ... ``` 当用户首次访问该网站是由于没有token,会先跳转到登录页,进行登录 ```javascript // 处理登录 function handleLogin() { // 参数校验 if (loginFromRef.value) { loginFromRef.value.validateField().then(() => { // 动画 isLoading.value = true // 发请求 store .dispatch('user/login', loginForm) .then(() => { // 如果有重定向参数redirect,将进行重定向 router.push({ path: route.query.redirect ? route.query.redirect : '/' }) ElMessage.success({ message: i18n.t('Login.index.808362-5') }) }) .finally(() => { isLoading.value = false }) }) } } ``` `store.dispatch('user/login', loginForm)`的实现如下: ```javascript login({ commit }, payload) { return new Promise((resolve, reject) => { login(payload) .then((data) => { // 登录成功,保存token commit('SET_token', data.token) resolve() }) .catch((error) => reject(error)) }) }, ``` 当登录成功后会保存服务器返回的token,并跳转首页,这时会再次进入导航守卫: ```javascript // 用已有的token去获取用户信息,看token是否过期 const ok = await store.dispatch('user/getUserInfo') ``` 由于有了token,会利用token去获取用户信息: ```javascript import { login, getUserInfo, logout } from '@/api/sys' 。。。 getUserInfo({ commit, dispatch }) { return new Promise((resolve, reject) => { getUserInfo() .then(async (data) => { // 保存用户信息到仓库 commit('SET_userInfo', data) // 等待路由计算完成 // 启用了命名空间的 getter 和 action 会收到局部化的 getter,dispatch 和 commit。 // 若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。 await dispatch('routes/computedUserRoutes', data.permission.menus, { root: true }) resolve(true) }) .catch(() => { // eslint-disable-next-line prefer-promise-reject-errors reject(false) }) }) }, 。。。 ``` 在这时候会根据用户的权限信息 `data.permission.menus`去计算用户所拥有的路由记录,这是实现权限控制的关键。服务端返回的 data 数据结构应该如下所示: ```javascript "data": { "id": 0, "role": [ 2 ], "openTime": "2023-05-04", "username": "admin", "avatar": "/favicon.ico", "permission": { "menus": [ "acl", "user-list", "role-list", "menu-list", "client-management" ], "points": [ "excel-import", "delete-user", "assign-role", "add-role", "delete-role", "assign-perm", "add-root-perm", "add-children-perm", "delete-perm" ] } }, ``` `menus`保存了可以访问的路由的`name`,这个值应该是唯一的。`points`保存了可以使用的按钮权限。 根据用户的权限信息 `data.permission.menus`去计算用户所拥有的路由记录的核心实现如下:
完整实现请查看:`src\store\modules\routes.js` ```javascript 。。。 computedUserRoutes({ commit }, menus) { return new Promise((resolve, reject) => { // 根据户信息计算出用户所拥有的路由表 const userPrivateRoutes = getUserPrivateRoutes(privateRoutes(), menus) // 将计算出的私有路由表添加到vue-router addRoutes(userPrivateRoutes) // 将用户拥有的私有路由与公有路由合并,保存到state.routes // state.routes主要用于:侧边栏渲染,页面搜索, commit('SET_routes', [...publicRoutes(), ...userPrivateRoutes]) commit('SET_userPrivateRoutes', userPrivateRoutes) resolve() }) }, 。。。 /** * 根据户信息计算出用户所拥有的路由表 * @param {*} flatPrivateRoutes * @param {*} menus */ function getUserPrivateRoutes(privateRoutes, menus) { // 不要在数组迭代中删除数组该数组中元素 const newList = [...privateRoutes] newList.forEach((route) => { // 从子路由开始向上遍历 if (route.children && route.children.length) { getUserPrivateRoutes(route.children, menus) } if (!(route.children && route.children.length)) { // 因为先过滤的子路由 // 如果过滤后,该路由还有子路由,不管你有没有该路由页面权限,都应该保留,否则看不到(不能添加到vue-router)子路由 // 如果没有子路由,我就要看看是否过滤该路由 const exist = menus.includes(route.name) if (!exist) { privateRoutes.splice(privateRoutes.indexOf(route), 1) } } }) return privateRoutes } ``` 当获取用户信息成功,动态路由也计算完成后,再回到我们的导航守卫中: ```javascript // 用已有的token去获取用户信息,看token是否过期 const ok = await store.dispatch('user/getUserInfo') if (ok) { // 没有过期,放行 // 由于在导航守卫中添加了动态路由,所以需要重定向,而不是直接next() next(to.fullPath) } ``` 此时就会跳转到要去的页面了。 所以,要使用该项目的RBAC功能,请配合后端规划好API接口以及请求/响应数据。请查看API接口文档了解更多。 ## SvgIcon 组件 SvgIcon组件已经在main.js 中进行全局注册,可以直接使用: ```javascript // 注册SvgIcon为全局组件 import SvgIcon from '@/components/SvgIcon' const app = createApp(App) .use(store) .use(router) .use(I18N) .use(ElementPlus, elementPlusConf) app.component('SvgIcon', SvgIcon) ``` 具体实现方式可以查看:`**src\components\SvgIcon\index.vue**`**。**
使用方式:
使用`hoverScale`这个`props`可以让鼠标悬浮图标时有缩放效果。
使用`icon` 这个`props`进行传参,可接收:
1.图标字体类名
2.svg的url
3.'`my-`'+本地`src/assets/icon/svg`中的svg名称,例如:`icon="my-login"` ```markdown ``` ## 明暗主题功能 明暗切换组件在 `src\components\LightDarkSwitch\index.vue` ```vue const isDark = useDark({ selector: 'html', // 要为哪一个元素添加属性,默认添加的属性名为class。element-plus的drak类必须添加在html标签上 valueDark: props.normalMode ? 'theme-dark dark' : 'theme-filter-invert-light theme-filter-invert-dark', // 添加的属性值,drak是 element-plus 的暗夜样式的类(https://element-plus.gitee.io/zh-CN/guide/dark-mode.html) valueLight: props.normalMode ? 'theme-light' : 'theme-filter-invert-light' }) ``` 当切换主题时,会更改html元素上的css类名,以更改不同的样式类,实现不同的样式效果。
具体的明暗css样式实现,可以查看和修改 `src\style`中的文件。 ```vue ├─style │ index.scss │ mobile.scss //一些通用的全局移动端样式 │ theme-dark.scss //暗夜主题样式 │ theme-filter-invert-dark.scss //使用css-filter 实现暗夜主题样式 │ theme-filter-invert-light.scss //使用css-filter 实现明亮主题样式 │ theme-light.scss //明亮主题样式 │ variables-dark.scss //暗夜主题使用的颜色变量 │ variables-light.scss //明亮主题使用的颜色变量 │ variables.scss //一些样式变量 ``` ## setting.js配置文件 ```vue import i18n from '@/i18n' export default { /** * 页面标题 */ pageTile: i18n.$t('src.settings.808362-0'), /** * 侧边栏 */ sideBar: { // sideBarLogo: { // isShow: true, // type: 'text', // 'text'or'img' // value: '后台管理系统' // }, sideBarLogo: { isShow: true, type: 'img', // 'text'or'img' value: '/favicon.ico' }, uniqueOpened: true, // 是否只保持一个子菜单的展开 // 侧边栏宽度 initWidth: 200, // 初始宽度,填写整数,单位是px minDargWidth: 180, // 最小宽度 maxDargWidth: 250, // 最大宽度 mobileCollapseToZero: true // 为移动端页面时,收缩侧边栏宽度到0 }, /** * 顶部导航栏 */ narBarFixed: true, // 是否固定导航条 narBarSeparator: '/' // 面包屑分隔符 } ``` `pageTile`文档标题后缀,可以自行修改,前面会拼接上菜单项的名称,可以在 `src\utility\set-document-title.js` 中修改拼接行为。
![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694158870597-4c186bfc-8439-4e7c-a8bb-6bcac5283634.png#averageHue=%23fdfbfb&clientId=u7d95f409-0a57-4&from=paste&height=687&id=u7df80999&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=140581&status=done&style=none&taskId=u164731c5-0461-43ca-bdff-f13d25f88be&title=&width=1280) ## Layout/布局样式 可以自行修改 `src\layout`中的布局文件。 ## 国际化/i18n功能 ### 具体实现 关于i18n的实现,可以查看如下文件:
`src\layout\NavBar\index.vue`
`src\components\LanguageSwitch\index.vue`
`src\i18n\index.js` ### 手动添加 #### 添加译文到json文件 在`src\i18n\locale\en.json`添加英文译文
![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694160753739-0c103b73-14ff-46ea-9f3c-cc8f0a160d32.png#averageHue=%23edeceb&clientId=u7d95f409-0a57-4&from=paste&height=687&id=u43713a9a&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=319433&status=done&style=none&taskId=ue5be295d-ded5-4576-8bf6-9767718a631&title=&width=1280)
在`src\i18n\locale\zh.json`中添加中文译文
![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694160905126-d1a697c8-e570-41dc-b2d5-25b0b018a48e.png#averageHue=%23edeceb&clientId=u7d95f409-0a57-4&from=paste&height=687&id=u7df28c1a&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=418348&status=done&style=none&taskId=ua11479dd-90e6-4ab7-b175-6aa80bb6850&title=&width=1280)
注意,此处的`key`均为:`404.index.808362-0` #### 在vue模板中使用 ![image.png](https://cdn.nlark.com/yuque/0/2023/png/34576819/1694161040009-77968710-032c-4ba2-85ce-0d45f7645974.png#averageHue=%23edebea&clientId=u7d95f409-0a57-4&from=paste&height=687&id=ud9c574f0&originHeight=1030&originWidth=1920&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=275345&status=done&style=none&taskId=u84ac45bf-62ac-4f7d-9652-ccb59671778&title=&width=1280) ```vue

{{ $t('404.index.808362-0') }}

``` 此处的`$t`方法已经挂载到了全局 #### 在