This commit is contained in:
张成
2026-03-24 11:18:40 +08:00
parent 6de4936012
commit c3623d4a95
4 changed files with 380 additions and 10 deletions

374
README.md
View File

@@ -0,0 +1,374 @@
# Admin Frameworkadmin-framework
基于 **Vue 2**、**Vue Router 3**、**Vuex 3**、**View DesigniView 4** 的后台管理框架登录、布局、动态菜单与路由、权限、HTTP 封装、系统管理页面等。
---
## 1. 依赖与环境
### 1.1 Peer 依赖(由业务项目安装)
框架不打包以下依赖,需在宿主项目中安装并与框架版本兼容:
| 包 | 说明 |
|----|------|
| `vue` ^2.6 | 运行时 |
| `vue-router` ^3 | 路由 |
| `vuex` ^3 | 状态 |
| `view-design` ^4 | UI 组件库 |
| `axios` | HTTP与框架内封装配合 |
### 1.2 构建产物(`dist/`
| 文件 | 说明 |
|------|------|
| `admin-framework.js` | **UMD**Terser 压缩,对外默认导出为框架单例;浏览器中为 `window.AdminFramework`,也可由 Webpack 等从该文件解析 `import` |
在项目根目录执行:
```bash
npm run build
```
---
## 2. 引入方式
### 2.1 与 Webpack / Vue CLI 等业务工程配合
先安装 peer 依赖,将构建好的 `dist/admin-framework.js` 拷贝到业务项目或通过路径引用;在入口中:
```javascript
import AdminFramework from './vendor/admin-framework.js'
// 若已将包发布到 npm 且 package.json 的 main 指向 dist
// import AdminFramework from 'admin-framework'
```
打包器需将 `vue``vue-router``vuex``view-design``axios` 作为外部依赖或正常解析(与 UMD 的 externals 一致)。
### 2.2 页面中通过 `<script>` 引入
按顺序引入 Vue、VueRouter、Vuex、View Design、axios 的 UMD 脚本,再引入 `admin-framework.js`,使用全局 **`AdminFramework`** 调用 `createApp` 等 API。
---
## 3. 核心 API一键创建应用
### 3.1 `AdminFramework.createApp(config)`
创建并配置 Vue 根实例:注册插件、全局属性、`componentMap`、Store、Router、布局等。**返回 Vue 实例**,需自行 `$mount`
**`config` 常用字段:**
| 字段 | 类型 | 说明 |
|------|------|------|
| `title` | `string` | 站点标题;未登录或接口失败时用作默认 `document.title` |
| `apiUrl` | `string` | 后端 API 根地址(必填,用于 `http` baseURL |
| `uploadUrl` | `string` | 可选;不传时由 `apiUrl` 自动推导为 `apiUrl + 'upload'``apiUrl + '/upload'` |
| `componentMap` | `object` | 动态路由组件映射,见 [§7](#7-组件映射与动态路由) |
| `HomePage` | `Vue` 组件 | 可选,自定义首页;默认框架内置欢迎页 |
| `onReady` | `function` | 可选,根实例 `created` 末尾调用,`this` 为 Vue 根实例 |
**示例:**
```javascript
import AdminFramework from 'admin-framework'
import componentMap from './router/component-map.js'
const app = AdminFramework.createApp({
title: '某某管理系统',
apiUrl: 'https://api.example.com/admin_api/',
componentMap,
HomePage: null,
onReady() {
console.log('框架与路由就绪', this.$route.path)
}
})
app.$mount('#app')
```
---
## 4. 框架实例(`AdminFramework` / `window.framework`
默认导出为**单例**。构建后也会挂到 `window.framework`(浏览器环境)。
### 4.1 常用属性
| 属性 | 说明 |
|------|------|
| `version` | 框架版本号字符串 |
| `config` | 最近一次 `createApp` 传入的配置 |
| `store` | Vuex Store 实例(`createApp` 之后可用) |
| `router` | Vue Router 实例 |
| `HomePage` | 当前使用的首页组件引用 |
| `http` | HTTP 封装实例,同 [§5](#5-http-模块) |
| `uiTool` | UI 与菜单工具类,同 [§6](#6-uitool-模块) |
| `tools` | 工具方法集合,同 [§6.2](#62-通用工具-tools) |
| `systemApi` | `src/api/system` 聚合导出,同 [§8](#8-系统-api-systemapi) |
| `pages` | 框架内置页面组件集合(登录、错误页、部分系统页等) |
| `components` | 布局与子组件导出Main、TreeGrid 等) |
| `storeModules` | 默认 `user``app` 模块描述,扩展 Store 时可参考 |
| `createBaseRoutes` / `setupRouterGuards` / `registerComponents` | 高级自定义路由/组件时使用 |
### 4.2 `addComponentMap(customMap)`
在运行时追加组件映射(与 `createApp` 里的 `componentMap` 语义相同)。
```javascript
import Games from './views/ball/games.vue'
AdminFramework.addComponentMap({
'ball/games': Games,
'ball/games.vue': Games
})
```
### 4.3 `initHttp(config, store)`
若未走 `createApp`、自行组装 Store 时,可用此方法初始化 `http`(一般使用 `createApp` 即可,内部已调用)。
```javascript
AdminFramework.initHttp(
{ apiUrl: 'https://api.example.com/admin_api/', timeout: 60000 },
storeInstance
)
```
---
## 5. HTTP 模块
通过 **`this.$http`**(组件内)或 **`AdminFramework.http`** / **`window.framework.http`** 访问。
### 5.1 初始化
`createApp({ apiUrl, ... })` 自动完成;请求头会带 `admin-token`(来自 `store.state.user.token`)。
### 5.2 约定
- 成功:后端 JSON 需 `code === 0`,否则走全局错误提示并 `reject`
- `401`:清空 token并跳转登录路由依赖 `window.framework.router`)。
### 5.3 方法说明
| 方法 | 说明 |
|------|------|
| `init(config, store)` | 合并 `timeout` 等,绑定 Store |
| `baseUrl()` | 当前 `apiUrl` |
| `ImgSrc(src)` | 拼接图片完整 URL`baseUrl() + src` |
| `getHttpInstance(extra)` | 返回带拦截器的 `axios` 实例 |
| `get(url, params, config)` | GET`params` 会序列化Date 会格式化为字符串 |
| `post(url, body, config)` | POST JSON |
| `postFormData(url, data)` | `application/x-www-form-urlencoded` |
| `fileExport(url, param, filename, is_down)` | 下载导出;内部可用 `uiTool.downloadFile` |
| `formatParamete` / `formatFormDataParam` | 参数预处理 |
| `showLoad` / `hideLoad` / `showError` | 与全局 loading、Message 联动 |
**示例(在 Vue 组件中):**
```javascript
export default {
async mounted() {
try {
const res = await this.$http.get('/sys_user/index', { page: 1, pageSize: 20 })
this.list = res.data
} catch (e) {
// 已全局提示
}
}
}
```
隐藏 loading
```javascript
await this.$http.get('/xxx', { id: 1 }, { hideLoad: true })
```
---
## 6. uiTool 模块
通过 **`this.$uiTool`** 或 **`AdminFramework.uiTool`** 使用(类静态方法)。
| 方法 | 说明 |
|------|------|
| `setComponentMap(map)` | 合并组件映射表 |
| `getComponent(path)` | 按路径取组件,`path` 可带或不带 `.vue` |
| `downloadFile(res, fileName)` | Blob 下载 |
| `setRem()` | 根据屏宽设置根字体(自适应) |
| `getImgSrc(src)` | 图片地址(同 http 规则) |
| `getBtn(h, options)` | Render 函数里生成操作按钮组 |
| `getDropdown(h, items)` | 下拉更多菜单 |
| `delConfirm(callback)` | 删除确认框 |
| `showConfirm({ title, content }, callback)` | 通用确认框 |
| `transformTree(list, cb)` | 扁平列表转树 |
| `subTree` / `menuToRoute` / `getRoutes` | 菜单转路由(框架内部与权限菜单配合) |
**树表示例:**
```javascript
const tree = this.$uiTool.transformTree(flatListFromApi)
```
---
## 6.2 通用工具 `tools`
通过 **`this.$tools`** 使用(具体以源码 `src/utils/tools.js` 为准)。
常用包括:
- **Cookie / Token**`getToken``setToken``TOKEN_KEY`
- **日期**`formatDate(val, fmt)`dayjs
- **数组**`forEach``hasOneOf``getUnion``getIntersection`
- **对象**`objEqual``removeEmptyObject``isNullorEmpty`
- **路由/菜单**`getBreadCrumbList``getHomeRoute``getMenuByRouter``filterMenu`
- **本地存储**`localSave``localRead`
- **其它**`generateUUID``getUrlParam``downStream``scrollTop`
**示例:**
```javascript
if (this.$tools.getToken()) { /* 已登录 */ }
```
---
## 7. 组件映射与动态路由
后端菜单里配置的「组件地址」会对应到**字符串路径**(如 `system/sys_user`)。框架通过 **`componentMap`** 把路径映射到真实 Vue 组件。
**在 `createApp` 中传入:**
```javascript
import SysUser from './views/system/sys_user.vue'
AdminFramework.createApp({
apiUrl: '...',
componentMap: {
'system/sys_user': SysUser,
'system/sys_user.vue': SysUser
}
})
```
未映射的路径会显示占位提示(控制台 `warn`),便于排查。
框架内置已注册一批系统页(如 `system/sys_menu` 等),见 `src/views/index.js``setupComponentMap`;业务模块在 `componentMap` 中追加即可。
---
## 8. 系统 API`systemApi`
`AdminFramework.systemApi` 聚合导出 `src/api/system` 下各 `*Server`,例如:
| 导出名 | 模块文件 | 典型用途 |
|--------|----------|----------|
| `userServer` | `userServer.js` | 登录、用户 CRUD、权限菜单 |
| `menuServer` | `menuServer.js` | 菜单管理 |
| `roleServer` / `rolePermissionServer` | 角色与权限 |
| `paramSetupServer` | 系统参数如站点标题、Logo |
| `fileServe` | 文件上传下载 |
| `modelServer` / `tableServer` / `formServer` 等 | 低代码/表单相关 |
**调用示例:**
```javascript
const { userServer } = AdminFramework.systemApi
async function login() {
const res = await userServer.login({ username: 'admin', password: '***' })
if (res.code === 0) {
// 写入 token、拉菜单等由登录页与 store 配合完成
}
}
```
实际请求仍走全局配置的 `http``apiUrl`、token 头)。
---
## 9. Vuex`this.$store`
默认模块:
### 9.1 `user``namespaced: true`
| 项 | 说明 |
|----|------|
| `state` | `token``userName``authorityMenus``menuList` 等 |
| `mutations` | `setToken``setUserName``setAuthorityMenus``setMenuList` |
| `actions` | `setAuthorityMenus`:拉取或传入菜单 JSON生成动态路由并写入 `localStorage` |
**登录后刷新菜单示例:**
```javascript
await this.$store.dispatch('user/setAuthorityMenus', {
Main: this.$framework.components.Main,
ParentView: this.$framework.components.ParentView,
Page404: this.$framework.pages.Page404,
HomePage: this.$framework.HomePage
})
```
(具体参数以当前框架版本 `user` 模块为准。)
### 9.2 `app``namespaced: true`
| 项 | 说明 |
|----|------|
| `state` | `sysFormModel`标题、Logo、面包屑、首页路由 |
| `actions` | `getSysTitle`:根据参数与接口更新站点标题与 Logo |
```javascript
await this.$store.dispatch('app/getSysTitle', {
defaultTitle: this.$config.title,
defaultLogo: ''
})
```
---
## 10. 全局 Vue 原型(组件内)
| 属性 | 说明 |
|------|------|
| `this.$config` | `createApp``config` |
| `this.$http` | HTTP 封装 |
| `this.$tools` | 工具集 |
| `this.$uiTool` | UI 工具类 |
| `this.$framework` | 框架单例(同 `AdminFramework` |
---
## 11. 内置页面与组件(`pages` / `components`
- **页面**`LoginPage``Page401``Page404``Page500` 及多套 `system/*` 管理页(见 `src/views/index.js` 导出)。
- **布局**`Main``ParentView`
- **通用组件**`TreeGrid``Tables``editModal``UploadSingle` / `UploadMultiple``Editor` 等(见 `src/components/index.js`)。
二次封装时可:
```javascript
const { TreeGrid, Main } = AdminFramework.components
```
---
## 12. 调试
- 浏览器中:`window.framework``window.rootVue`(根实例,在 `createApp` 创建后设置)。
- 需要未压缩源码调试时,可在业务工程里直接引用框架 **`src/index.js`**(需配置好 alias、loader 与 peer 依赖),或使用浏览器「在源映射中黑盒脚本」等能力。
---
## 13. Demo 项目
`demo/` 为示例:请先在**仓库根目录**执行 `npm run build` 生成 `dist/admin-framework.js`,再在 `demo` 目录安装依赖并执行 `npm run dev``demo/src/main.js` 通过相对路径引用上级 `dist` 中的 UMD 包。
---
以上为框架对外使用方式的说明;内部实现以 `src/` 源码为准。若升级版本,请同时核对 peer 依赖与本文档中的 API 是否变更。

View File

@@ -240,13 +240,11 @@ const config = {
## 开发建议
1. **开发时使用 build:dev**
- 生成 sourcemap方便调试
- 代码不压缩,易读
1. **框架产物**
- 在仓库根目录执行 `npm run build`,生成 `dist/admin-framework.js`UMD、压缩
2. **生产时使用 build**
- 代码压缩,体积小
- 无 sourcemap安全
2. **调试**
- 需要跟源码时可在业务工程中直接引用框架 `src/index.js` 并配置 Webpack或使用 `window.framework` / `window.rootVue`
3. **使用浏览器调试工具**
```javascript

View File

@@ -5,10 +5,8 @@
"main": "dist/admin-framework.js",
"scripts": {
"build": "webpack --mode production",
"build:dev": "cross-env NODE_ENV=development webpack --mode production",
"dev": "webpack --mode development --watch",
"serve": "npm run build && npx http-server -p 8080 -o /demo/index.html",
"serve:dev": "npm run build:dev && npx http-server -p 8080 -o /demo/index.html"
"serve": "npm run build && npx http-server -p 8080 -o /demo/index.html"
},
"keywords": [
"admin",
@@ -45,7 +43,6 @@
"@babel/preset-env": "^7.12.0",
"autoprefixer": "^10.4.21",
"babel-loader": "^8.2.0",
"cross-env": "^10.1.0",
"css-loader": "^5.0.0",
"file-loader": "^6.2.0",
"less": "^4.0.0",

View File

@@ -54,6 +54,7 @@ export function setupComponentMap(customMap = {}, uiTool) {
}
export default {
HomePage,
SysLog,
SysLogOperate,
SysParamSetup,