一、创建
基于Vue3、ElementPlus框架、工程化工具Vite进行构建。此模板可用于现代化管理系统的初始开发模板,可节省一些重复性的工程初始化搭建工作。
二、特性
- 使用pnpm作为包下载工具,下载包请先执行npm i pnpm -g,再使用pnpm i
- 默认使用axios请求数据和mockjs来模拟数据。
- 使用nprogress插件来作为单页面切换的加载指示器。
- 使用VueRouter动态生成不同角色菜单的路由权限。
- 基本的兼容性提醒,由于vite和vue3不兼容IE浏览器,因此如检测为IE浏览器则提醒用户切换使用其他浏览器。
三、使用库/工具
- Pnpm
- Vue 3
- VueRouter 4.x(有兼容
vue3
语法的hook
写法) - Vuex 4.x (有兼容
vue3
语法的hook
写法) - Vite 2.x
- ElementPlus
- dayjs(一个轻便的时间处理库)
- axios (好用的 http 请求库)
- mockjs (模拟请求)
- reset-css (重置浏览器默认样式)
- nprogress (顶部加载指示器)
- vite-plugin-compression(打包压缩 gzip 插件)
- @rollup/plugin-strip (打包去除调试语句插件)
- visualizer (打包文件大小占比分析可视化插件)
四、模板主要结构
framework-admin-vue3
├─ public
(public 文件夹)
│ └─ favicon.ico
浏览器标签前缀图标
│
├─ src
(根目录 src-文件夹)
│ ├─ assets
(资源-文件夹)
│ │ └─ images
(图片-文件夹)
│ │
│ ├─ components
(全局公共-文件夹)
│ │
│ ├─ hooks
(自定义 hooks-文件夹)
│ │ ├─ useTableData.js
│ │ └─ useWindowRect.js
│ │
│ ├─ http
(http 请求-文件夹)
│ │ ├─ apis
(api 管理-文件夹)
│ │ │ ├─ role-management.js
│ │ │ ├─ user-management.js
│ │ │ └─ user.js
│ │ ├─ axios.js
(axios 配置文件)
│ │ └─ index.js
(http 请求主入口文件)
│ │
│ ├─ layouts
(布局文件夹)
│ │ ├─ AppHeader
(头部组件-文件夹)
│ │ │ └─ index.vue
│ │ ├─ AppSideBar
(侧边栏菜单组件-文件夹)
│ │ │ ├─ index.vue
│ │ │ └─ MenuItem.vue
│ │ ├─ Breadcrumb
(面包屑组件-文件夹)
│ │ │ └─ index.vue
│ │ ├─TagsViewSwitcher
(标签切换组件-文件夹)
│ │ │ └─ index.vue
│ │ └─ AdminLayout.vue
(管理端页面布局组件)
│ │
│ ├─ mock
(mock 模拟数据-文件夹)
│ │ ├─ apiController
(controller-文件夹)
│ │ │ ├─ role-management.js
│ │ │ ├─ user-management.js
│ │ │ └─ user.js
│ │ ├─ index.js
(mock 主入口文件)
│ │ └─ mock.js
(mock 配置文件)
│ │
│ ├─ pages
│ │ ├─ 404
(404 页面-文件夹)
│ │ │ └─ index.vue
│ │ ├─ home
(首页-文件夹)
│ │ │ └─ index.vue
│ │ ├─ login
(登录注册页面-文件夹)
│ │ │ └─ index.vue
│ │ ├─ role-management
(角色管理页-文件夹)
│ │ │ ├─ components
(页面子组件-文件夹)
│ │ │ │ └─ RoleEdit.vue
│ │ │ └─ index.vue
│ │ └─user-management
(用户管理页-文件夹)
│ │ ├─ components
(页面子组件-文件夹)
│ │ │ └─ UserEdit.vue
│ │ └─ index.vue
│ │
│ ├─ router
(路由文件夹)
│ │ └─ index.js
vueRouter 主入口
│ │
│ ├─ store
(文件夹)
│ │ ├─ modules
(store 模块文件夹)
│ │ │ ├─ app.js
(app 配置模块)
│ │ │ ├─ options.js
(全局下拉值选项模块)
│ │ │ └─ tags-view.js
(页面标签切换模块)
│ │ └─ index.js
(store 主入口)
│ │
│ ├─ styles
(全局样式-文件夹)
│ │ ├─ animation.scss
(css 动画样式表)
│ │ ├─ color.scss
(颜色变量样式表)
│ │ ├─ custom-default-browser-style.scss
(自定义浏览器默认样式表)
│ │ ├─ elementui-variables.scss
(自定义 elementPlus 默认主题和样式表)
│ │ ├─ global.scss
(全局样式表)
│ │ └─ mixin.scss
(scss 的 mixin 样式表)
│ │
│ ├─ others
(其他-文件夹)
│ │ ├─ utils.js
(工具函数文件)
│ │ ├─ options.js
(下拉值文件)
│ │ └─ validator.js
(值校验函数文件)
│ │
│ ├─ App.vue
(项目主组件)
│ └─ main.js
(项目主入口)
│
├─ index.html
(页面挂载文件)
├─ package.json
(npm 配置文件)
├─ README.md
(项目文档)
└─ vite.config.js
(vite 配置文件)
五、关键点介绍
-
重置浏览器默认样式
请参考
style
文件夹下的custom-default-browser-style.scss
文件,本文件修改浏览器默认滚动条样式。
更多的浏览器样式重置则使用了 npm 插件reset-css
,在项目主入口文件main.js
中引入。
-
useTableData
自定义 hook,用于封装表格查询的可复用逻辑和操作,在需要表格查询操作的页面或组件中引入即可。详细请查看
hooks
文件夹下的useTableData.js
文件。//使用举例 import useTableData from "@/hooks/useTableData.js"; //传入以Promise封装的http请求api const table = useTableData(fetchTableDataApi); //设置参数,发起请求 table.setParams({ keyword: keyword, ... }); //重置请求 table.reset(); //刷新请求 table.refresh() //表格请求参数(默认字段 currentPage,pageSize ) console.log(table.tableParams); //表格分页器分页组配置(默认值 [20, 50, 100] ) console.log(table.PAGE_SIZES); //表格数据(默认字段 list,totalCount,isLoading ) console.log(table.tableData);
-
useWindowSize 与动态表格高度
当固定表头时需要限制 elementUI 表格高度,数据则会表现为溢出滚动,如页面缩放的时候需要占满屏幕,则可监测浏览器高度
clientHeight
动态赋值表格高度,以达到缩放浏览器窗口表格大小不变的效果。
useWindowRect
封装了监听浏览器宽高的可复用逻辑,此 hook 将动态的clientHeight
和clientWidth
值设置存储到 vuex 的store/modules/app.js
文件内的windowRect
字段,因此每个页面可引入动态的宽高值来设置表格高度。
-
菜单权限和动态路由
如管理系统的权限是根据菜单管理页面和权限配置页面来设置的并且通过后端返回菜单区分账号权限,则前端可在登录时根据返回的菜单渲染侧边栏菜单和使用
VueRouter
的router.addRoute
API 来动态添加路由。
动态添加路由会在浏览器刷新时丢失,可把菜单用localStorage
缓存,每次刷新浏览器都动态添加一次路由即可解决。
退出登录时需要清除动态添加的路由,可使用 resetRouter 进行重置路由。function resetRouter() { const newRouter = createRouter({ routes: constantRoute, history: createWebHashHistory(), }); router.matcher = newRouter.matcher; }
-
面包屑
最简单的处理方式就是根据后端返回的菜单设置个
breadcrumb
数组字段处理即可,如有其它需求可根据实际数据情况而定。{ id: "1", name: "系统管理", icon: "el-icon-setting", url: "/system", breadcrumb: ["系统管理"], type: "group", children: [{ id: "1-1", name: "用户管理", icon: "", type: "page", url: "/system/user-management", children: null, breadcrumb: ["系统管理", "用户管理"], }] }
-
系统设置
可配置化或用户自行选择。
- 页面指示:
可选标签切换
/面包屑
- 页面状态缓存:
当页面指示为标签切换
时可选页面切换时是否缓存页面状态,使用<keep-alive>
组件缓存。
- 菜单栏折叠。
- 页面指示:
-
右键自定义菜单与Teleport
当指示器为
标签切换
时,标签切换栏区域点击右键出现自定义菜单,可删除全部已打开的标签;
自定义右键菜单采用Vue3新特性teleport
的方式加载到body
元素里面,防止父元素定位干扰。右键自定义菜单 <teleport to="body"> <div class="context-menu" > xxx </div> </teleport>
-
http请求与axios全局请求配置
全局请求配置文件在
/src/http/axios.js
下配置;请求接口按页面模块进行分类,页面名称对应api接口文件名称,存放在/src/http/apis/
文件夹下,再通过/src/http/index.js
文件进行统一导出。// http接口请求使用 import http from "@/http"; http.[页面模块名称].xxx() 如 http.roleManagement.tableList()
-
Mockjs模拟数据
所有数据均来自本地mock模拟数据,位于
/src/mock
文件夹下。
/src/mock/mock.js
为mock全局配置
/src/mock/apiController
文件夹为所有模拟接口请求处理
在/src/main.js
下引入mock文件即可使用接口,如import "./mock/index";
-
环境切换
根据项目的根目录下的
.env.xxx.
文件区分环境,以VITE_
开头的字段可在import.meta.env
中获取。如有更多需求可自行添加。.env.development
开发环境.env.production
正式环境
-
Vite基本命令
// package.json "scripts": { "dev": "vite", //开启热更新服务器 "build": "vite build", //打包项目 "preview/dist": "vite preview" //本地预览打包的项目 }
-
Vite基本配置
// vite.config.js配置文件 import vue from "@vitejs/plugin-vue"; import { visualizer } from "rollup-plugin-visualizer"; import strip from "@rollup/plugin-strip"; import viteCompression from "vite-plugin-compression"; const path = require("path"); export default { base: './', plugins: [ vue(), //正式环境打包查看各文件大小占比 visualizer({ open: true, gzipSize: true, brotliSize: true, }), //正式环境打包去除调试语句 { ...strip({ include: ["**/*.js", "**/*.vue", "**/*.ts", "**/*.jsx"], }), apply: "build", }, //打包开启gzip压缩 viteCompression(), ], resolve: { alias: { // 键必须以斜线开始和结束 "@": path.resolve(__dirname, "./src"), }, }, css: { preprocessorOptions: { scss: { //添加scss全局变量样式 additionalData: "@import './src/styles/global.scss';", }, }, }, server: { // 配置调试服务器主机名,如果允许外部访问,可设置为"0.0.0.0" host: "0.0.0.0", port: 3000, // 服务器端口号 open: true, // 是否自动打开浏览器 }, };
六、注意
- Vite 工具打包不兼容任何版本的 IE 浏览器(和 Webpack 打包机制不同)。
- Vue 3 不兼容IE浏览器。
- icon使用方式见main.js需要加前缀icon-