768 lines
26 KiB
Markdown
768 lines
26 KiB
Markdown
# Admin Framework(admin-framework)
|
||
|
||
基于 **Vue 2**、**Vue Router 3**、**Vuex 3**、**View Design(iView 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`)
|
||
|
||
- **页面**:`LoginPage`、`Page401`、`Page404`、`Page500`、`HomePage` 及多套 `system/*` 管理页(见 `src/views/index.js`)。
|
||
- 业务中也可通过 `AdminFramework.pages` 取到上述导出。
|
||
|
||
---
|
||
|
||
## 12. 组件使用说明(`src/components`)
|
||
|
||
`createApp` 执行时会对下列组件**全局注册**(见 `src/components/index.js` 中 `registerGlobalComponents`),在任意 `.vue` 模板中可直接写 **PascalCase 或 kebab-case** 标签名(如 `<Tables>` / `<tree-grid>`)。也可按需:
|
||
|
||
```javascript
|
||
import { Tables, TreeGrid, editModal } from 'admin-framework'
|
||
// 或在源码工程中:import Tables from '@/components/tables'
|
||
const { TreeGrid, Main } = AdminFramework.components
|
||
```
|
||
|
||
以下按功能分类;**Props / 事件以源码为准**,此处列出常用项。
|
||
|
||
### 12.1 布局与路由壳
|
||
|
||
| 组件 | 说明 |
|
||
|------|------|
|
||
| **Main** | 后台主布局:左侧 `SideMenu`、顶栏 `HeaderBar`、用户信息、`Terminal`、主内容区 `<router-view />`、内嵌 `LoadFlower`、返回顶部。无业务 Props,标题/Logo 来自 Vuex `app/sysFormModel`,菜单来自 `user/menuList`。 |
|
||
| **ParentView** | 仅渲染一层 `<router-view />`,用于菜单多级嵌套时的中间层。 |
|
||
|
||
```vue
|
||
<!-- 动态路由中由框架注册,一般不在页面手写 Main -->
|
||
```
|
||
|
||
#### Main 子模块说明(`src/components/main/components`)
|
||
|
||
以下组件**默认未在 `registerGlobalComponents` 中注册**,由 **Main** 内部引用;若要在自定义布局中复用,需从路径手动 `import`(示例路径以源码工程 `@/components/...` 为准)。
|
||
|
||
**组合关系(`main.vue`)**:`Layout` 左侧为 `SideMenu` + 品牌区;右侧顶部 `HeaderBar`,其默认插槽内为 `Terminal` 与 `User`;内容区为 `<router-view />`、`LoadFlower`、`ABackTop`。
|
||
|
||
---
|
||
|
||
**1. `SideMenu`(`side-menu/side-menu.vue`)**
|
||
|
||
侧栏菜单,基于 iView `Menu`,支持折叠态下的 `CollapsedMenu` 下拉。
|
||
|
||
| Props | 类型 | 说明 |
|
||
|-------|------|------|
|
||
| `menuList` | `Array` | 菜单树,项需含 `name`、`meta`(如 `icon`、`title`)、子节点 `children` 等,与动态路由菜单结构一致 |
|
||
| `collapsed` | `Boolean` | 是否折叠(仅图标 / 下拉) |
|
||
| `theme` | `String` | 菜单主题,默认 `light`;Main 中传入 `dark` |
|
||
| `activeName` | `String` | 当前激活菜单 `name`,一般传 `$route.name` |
|
||
| `openNames` | `Array` | 初始展开的 Submenu 名称列表 |
|
||
| `rootIconSize` / `iconSize` | `Number` | 折叠/展开时图标大小,默认 `20` / `16` |
|
||
|
||
| 插槽 | 说明 |
|
||
|------|------|
|
||
| 默认 | 菜单上方的额外区域(可选) |
|
||
|
||
| 事件 | 说明 |
|
||
|------|------|
|
||
| `on-select` | 选中菜单项时,参数为路由 `name` 字符串(或外链特殊格式 `isTurnByHref_xxx`,由 Main 中 `turnToPage` 处理) |
|
||
|
||
```vue
|
||
<SideMenu
|
||
theme="dark"
|
||
:menu-list="menuList"
|
||
:collapsed="collapsed"
|
||
:active-name="$route.name"
|
||
@on-select="handleMenuSelect"
|
||
/>
|
||
```
|
||
|
||
**2. `SideMenuItem`(`side-menu/side-menu-item.vue`)**
|
||
|
||
`SideMenu` 内部递归子组件:渲染 `Submenu` 标题与一层子 `menu-item`。依赖 mixin 提供的 `parentItem`、`children` 等逻辑,**一般不单独使用**。
|
||
|
||
**3. `CollapsedMenu`(`side-menu/collapsed-menu.vue`)**
|
||
|
||
侧栏折叠时的下拉菜单(`Dropdown` 嵌套)。由 `SideMenu` 使用。
|
||
|
||
| Props | 说明 |
|
||
|-------|------|
|
||
| `parentItem` | 当前菜单节点 |
|
||
| `hideTitle` | 为 true 时仅图标(侧栏窄条场景) |
|
||
| `rootIconSize` / `iconSize` | 图标尺寸 |
|
||
| `theme` | 与侧栏主题一致,用于图标颜色 |
|
||
|
||
| 事件 | `on-click` — 点击子项时传出菜单 `name` |
|
||
|
||
---
|
||
|
||
**4. `HeaderBar`(`header-bar/header-bar.vue`)**
|
||
|
||
顶栏:左侧 **折叠开关** + **面包屑**,右侧 **默认插槽**(Main 里放终端图标、用户区等)。
|
||
|
||
| Props | 说明 |
|
||
|-------|------|
|
||
| `collapsed` | 当前侧栏是否折叠,传给 `SiderTrigger` |
|
||
|
||
| 插槽 | 说明 |
|
||
|------|------|
|
||
| 默认 | 顶栏右侧自定义内容(如 `Terminal`、`User`) |
|
||
|
||
| 事件 | 说明 |
|
||
|------|------|
|
||
| `on-coll-change` | 折叠按钮切换,`payload` 为**新的** `collapsed` 布尔值(与 `SiderTrigger` 的 `on-change` 一致) |
|
||
|
||
面包屑数据来自 **`$route.matched`**(去掉第一项),每项包含 `name`、`path`、`meta`;展示标题用 `tools.showTitle`。
|
||
|
||
```vue
|
||
<HeaderBar :collapsed="collapsed" @on-coll-change="collapsed = $event">
|
||
<Terminal /><User :userName="name" :user-avator="avatar" />
|
||
</HeaderBar>
|
||
```
|
||
|
||
**5. `SiderTrigger`(`header-bar/sider-trigger/sider-trigger.vue`)**
|
||
|
||
折叠侧栏的图标按钮。
|
||
|
||
| Props | `collapsed`、`icon`(默认 `navicon-round`,Main 里为 `md-menu`)、`size`(默认 `26`) |
|
||
| 事件 | `on-change` — 参数为切换后的 `collapsed` 状态(布尔) |
|
||
|
||
**6. `customBreadCrumb`(`header-bar/custom-bread-crumb/custom-bread-crumb.vue`)**
|
||
|
||
自定义面包屑(`Breadcrumb`)。
|
||
|
||
| Props | `list`( `{ name, path, meta, to?, icon? }[]` )、`fontSize`(默认 `14`)、`showIcon` |
|
||
| 说明 | 文案通过 `showTitle(item, this)` 解析,支持 `meta.title` 等 |
|
||
|
||
---
|
||
|
||
**7. `User`(`user/user.vue`)**
|
||
|
||
右上角用户名 + 头像下拉,**退出登录**走 Vuex `user/handleLogOut`。
|
||
|
||
| Props | `userName`、`userAvator`(字符串 URL;也可传对象,未用字符串时显示内置默认图) |
|
||
| 说明 | 内置 `message` 方法曾跳转 `message_page`,可按需扩展菜单项 |
|
||
|
||
**8. Terminal(`terminal/index.vue` + `terminal/terminal.vue`)**
|
||
|
||
入口为一颗 **iView `Icon`**,点击后用 **`AsyncModal`** 弹层展示内层终端视图。当前实现中日志区域为占位文案(**终端功能暂未启用**),按钮「重新加载 / 清空」会提示未启用。
|
||
|
||
复用时需保证工程内已注册 **`AsyncModal`**。`index.vue` 中 `ref="asyncModal"` 调用 `show()` 打开弹窗。
|
||
|
||
**9. `Language`(`language/language.vue`)**
|
||
|
||
语言下拉(`zh-CN` / `zh-TW` / `en-US`)。需在工程中配置 **`vue-i18n`**(`this.$i18n`)方可切换文案。
|
||
|
||
| Props | `lang` 当前语言代码 |
|
||
| 事件 | `on-lang-change` — 选中的语言 key |
|
||
|
||
> `main.vue` 当前模板未挂载 `Language`,若在自定义 Main 中需要多语言顶栏,可自行加入。
|
||
|
||
**10. `Fullscreen`(`fullscreen/fullscreen.vue`)**
|
||
|
||
全屏切换;非 IE 显示按钮。支持 **`v-model`**(`value` 是否全屏),全屏状态变化时触发 `input`、`on-change`。
|
||
|
||
> `main.vue` 当前未使用该组件,可按需放入 `HeaderBar` 插槽。
|
||
|
||
**11. `ABackTop`(`a-back-top/index.vue`)**
|
||
|
||
回到顶部浮动按钮,监听**滚动容器**滚动。
|
||
|
||
| Props | `height`(显示阈值,默认 `400`)、`bottom`、`right`、`duration`(滚动动画 ms)、`container`(默认 `window`,可为选择器字符串如 `'.content-wrapper'`) |
|
||
| 插槽 | 默认:自定义按钮外观;未提供时用内置箭头图标 |
|
||
| 方法 | 内部 `scrollTop` 滚动;点击触发回到顶部 |
|
||
|
||
Main 中示例:`<ABackTop container=".content-wrapper" :height="100" :bottom="80" :right="50" />`。
|
||
|
||
---
|
||
|
||
**小结**:自定义后台壳时,可照搬 `main.vue` 结构,替换或增删 `HeaderBar` 插槽内子组件;侧栏行为与菜单数据结构强相关,需与 **`user/menuList`**、**路由 `meta`** 保持一致。
|
||
|
||
### 12.2 表格:`Tables`
|
||
|
||
基于 View Design `Table` 封装,支持分页条、导出、列配置、可编辑列等。
|
||
|
||
| Props | 说明 |
|
||
|-------|------|
|
||
| `value` | 表格数据数组 |
|
||
| `columns` | 列配置(同 iView Table `columns`,框架内会做对齐等默认处理) |
|
||
| `title` / `tip` | 表格标题与灰色提示 |
|
||
| `isDown` | 为 true 且 `value` 非空时显示「下载」链接触发导出 |
|
||
| `pageOption` | 分页:`{ page, pageSize, total }`,存在则显示 `Page` |
|
||
| `width` / `height` | 传给内部 Table |
|
||
| `maxHeightOffset` | 表格外层最大高度:`auto`(默认,按视口计算)或数字,用于 `calc(100vh - offset)` |
|
||
|
||
| 插槽 | 说明 |
|
||
|------|------|
|
||
| `header` | 标题行右侧区域 |
|
||
| 默认 | 透传给内部 Table(如 `slot-scope` 列) |
|
||
| `footer` / `loading` | 透传 Table 同名插槽 |
|
||
|
||
| 事件 | 说明 |
|
||
|------|------|
|
||
| `changePage` | 分页变更(内部已更新 `pageOption.page`) |
|
||
| `on-select` | 多选变化 |
|
||
| `downExecl` | 点击下载时,`{ value, columns }` |
|
||
|
||
```vue
|
||
<Tables
|
||
:value="tableData"
|
||
:columns="columns"
|
||
:page-option="{ page: 1, pageSize: 10, total: 100 }"
|
||
title="用户列表"
|
||
@changePage="loadData"
|
||
/>
|
||
```
|
||
|
||
### 12.3 树形表格:`TreeGrid`
|
||
|
||
树形多级表格,表头与行由 `columns`、`data` 驱动(数据需含 `children` 等树结构)。
|
||
|
||
| Props | 说明 |
|
||
|-------|------|
|
||
| `columns` | 列配置 |
|
||
| `data` | 树形数据 |
|
||
|
||
其余属性通过 `v-bind="$attrs"` 传到内部子组件。
|
||
|
||
```vue
|
||
<TreeGrid :columns="gridOption.columns" :data="gridOption.data" />
|
||
```
|
||
|
||
### 12.4 上传:`UploadSingle` / `UploadMultiple`
|
||
|
||
| 组件 | 说明 |
|
||
|------|------|
|
||
| **UploadSingle** | 单图。`v-model` 绑定服务器返回的**相对路径**字符串;上传地址为 `apiUrl + 'sys_file/upload_oos_img'`,请求头带 `admin-token`。成功:`input`、`change`。预览/删除支持。 |
|
||
| **UploadMultiple** | 多图(内部列表最多约 4 张)。`@handleSuccess` 回调 `{ file, uploadList }`;可调用 `setList(list)` / `getList()` 同步列表。 |
|
||
|
||
```vue
|
||
<UploadSingle v-model="form.avatar" />
|
||
<UploadMultiple ref="multi" @handleSuccess="onUploaded" />
|
||
```
|
||
|
||
### 12.5 富文本:`Editor`
|
||
|
||
基于 **wangEditor**。使用 `this.$config.apiUrl`(或等价配置)作为图片上传地址。
|
||
|
||
| Props | 说明 |
|
||
|-------|------|
|
||
| `value` | HTML 字符串,支持 `v-model` |
|
||
|
||
```vue
|
||
<Editor v-model="form.content" />
|
||
```
|
||
|
||
### 12.6 弹窗:`AsyncModal` / `editModal`
|
||
|
||
**AsyncModal** — 简单确认弹窗:
|
||
|
||
| Props | 说明 |
|
||
|-------|------|
|
||
| `title` | 标题 |
|
||
| `width` | 宽度,默认约 `80`(Modal 数字宽度) |
|
||
|
||
| 方法 | 说明 |
|
||
|------|------|
|
||
| `show(callback)` | 打开;确定时**先**执行 `callback`(可 async),再 `on-ok` 并关闭 |
|
||
|
||
```vue
|
||
<AsyncModal ref="asyncModal" title="提示">
|
||
<p>自定义内容</p>
|
||
</AsyncModal>
|
||
<!-- this.$refs.asyncModal.show(async () => { await api(); }) -->
|
||
```
|
||
|
||
**editModal** — 由 `columns` 驱动表单项(内部用 `FieldRenderer`),用于新增/编辑:
|
||
|
||
| Props | 说明 |
|
||
|-------|------|
|
||
| `columns` | 列/字段配置:`key`、`title`、`com`(Input、Select、Radio、`editRender` 等) |
|
||
| `width` | 弹窗宽度 |
|
||
| `rules` | 可通过父级传入覆盖默认校验(与 `Form` 一致) |
|
||
|
||
| 插槽 | 说明 |
|
||
|------|------|
|
||
| `top` | 表单最上方 |
|
||
| `bottom` | 表单最下方(如额外表单项) |
|
||
|
||
| 方法 | 说明 |
|
||
|------|------|
|
||
| `addShow(row, callback)` | 新增;确定后 `callback(提交行数据)` |
|
||
| `editShow(row, callback)` | 编辑 |
|
||
| `showModal(row)` | 有 `id` 走编辑,否则新增 |
|
||
| `hide` / `setFooter` / `refresh` | 关闭、控制底部按钮、强制重渲染表单 |
|
||
|
||
| 事件 | 说明 |
|
||
|------|------|
|
||
| `on-save` | `{ data, isEdit }` |
|
||
| `on-visible-change` | Modal 显隐 |
|
||
|
||
```vue
|
||
<editModal ref="editModal" :columns="editColumns" :rules="rules">
|
||
<div slot="bottom"><fieldItem name="备注"><Input v-model="extra" /></fieldItem></div>
|
||
</editModal>
|
||
```
|
||
|
||
### 12.7 表单项辅助:`fieldItem` / `FieldRenderer`
|
||
|
||
| 组件 | 说明 |
|
||
|------|------|
|
||
| **fieldItem** | 简单包装:`name`(标签)、`required`,默认插槽放控件。 |
|
||
| **FieldRenderer** | 根据 `col.com` 渲染 Input、Select、Radio、`UploadSingle`、`DatePicker` 等;一般被 `editModal` 使用,也可在自定义表单中复用。 |
|
||
|
||
```vue
|
||
<fieldItem name="名称" :required="true">
|
||
<Input v-model="form.name" />
|
||
</fieldItem>
|
||
```
|
||
|
||
### 12.8 卡片:`InfoCard`
|
||
|
||
左侧色块 + 图标,右侧自定义内容。
|
||
|
||
| Props | 说明 |
|
||
|-------|------|
|
||
| `left` | 左侧宽度占比,默认 `36`(即 36%) |
|
||
| `color` | 左侧背景色 |
|
||
| `icon` / `iconSize` | 图标名与尺寸(走 `CommonIcon`) |
|
||
| `shadow` | 是否 Card 阴影 |
|
||
|
||
```vue
|
||
<InfoCard icon="md-person" color="#19be6b">
|
||
<p>自定义统计文案</p>
|
||
</InfoCard>
|
||
```
|
||
|
||
### 12.9 分割面板:`SplitPane`
|
||
|
||
可拖拽调整左右或上下比例。
|
||
|
||
| Props | 说明 |
|
||
|-------|------|
|
||
| `value` | `0~1` 或带 `px` 的字符串,初始分割位置 |
|
||
| `mode` | `horizontal`(左右)或 `vertical`(上下) |
|
||
| `min` / `max` | 拖拽极限,默认约 `40px` |
|
||
|
||
| 插槽 | 说明 |
|
||
|------|------|
|
||
| `left` / `right` 或 `top` / `bottom` | 两侧内容 |
|
||
| `trigger` | 自定义拖拽条 |
|
||
|
||
| 事件 | 说明 |
|
||
|------|------|
|
||
| `on-move-start` / `on-moving` / `on-move-end` | 拖拽过程;`on-moving` 事件对象上可带 `atMin`、`atMax` |
|
||
|
||
```vue
|
||
<SplitPane v-model="split" mode="horizontal">
|
||
<div slot="left">左</div>
|
||
<div slot="right">右</div>
|
||
</SplitPane>
|
||
```
|
||
|
||
### 12.10 侧滑层:`FloatPanel`
|
||
|
||
从一侧滑出的面板,带返回/关闭。
|
||
|
||
| Props | 说明 |
|
||
|-------|------|
|
||
| `title` | 标题 |
|
||
| `width` / `height` | 尺寸,支持数字或带单位字符串 |
|
||
| `position` | `left` / `right` / `top` / `bottom` / `center` |
|
||
| `showBack` / `backText` | 返回按钮与文案 |
|
||
| `showClose` | 右上角关闭 |
|
||
| `closeOnClickBackdrop` | 点击遮罩是否关闭 |
|
||
| `mask` | 是否遮罩 |
|
||
| `zIndex` | 层级 |
|
||
|
||
| 方法 | 说明 |
|
||
|------|------|
|
||
| `show(callback)` | 显示;可选回调 |
|
||
| `hide()` | 隐藏 |
|
||
|
||
| 插槽 | 说明 |
|
||
|------|------|
|
||
| 默认 | 主体内容 |
|
||
| `header-right` | 标题栏右侧 |
|
||
|
||
```vue
|
||
<FloatPanel ref="panel" title="详情" position="right" :width="480">
|
||
<p>内容</p>
|
||
</FloatPanel>
|
||
<!-- this.$refs.panel.show() -->
|
||
```
|
||
|
||
### 12.11 其他全局组件
|
||
|
||
| 组件 | 说明 |
|
||
|------|------|
|
||
| **TextArea** | 多行输入,`value` + `input` 事件,封装 iView `Input type="textarea"`。 |
|
||
| **CommonIcon** | `type`:普通 `Icon` 名;自定义图标以 `_` 开头配合 `md-icons`。`size`、`color` 可选。 |
|
||
| **LoadFlower** | 全屏 loading 占位(与 `http` 的 `showLoad` 通过 DOM `id` 联动),一般随 `Main` 挂载,无需单独使用。 |
|
||
|
||
### 12.12 未全局注册、按需引用的组件
|
||
|
||
以下在 `src/components` 下,需在页面中 **import** 后注册或局部引用:
|
||
|
||
| 路径/名称 | 说明 |
|
||
|-----------|------|
|
||
| `login-form` | 登录表单:`userNameRules`、`passwordRules`;校验通过 `@on-success-valid` 抛出 `{ userName, password }`。 |
|
||
| `date-picker/index.vue` | 对 `DatePicker` 的 `v-model` 封装,`change`/`input`。 |
|
||
| `switch/index.vue` | 对 `Switch` 的 `v-model` 封装。 |
|
||
| `cron-input` | Cron 表达式下拉选择。 |
|
||
| `main/pageHead.vue` | 页面顶栏条:当 `$route.meta.type === '功能'` 时显示返回;默认插槽放按钮。 |
|
||
| `markdown`、`cropper` 等 | 见各目录 `index.js` / 入口组件。 |
|
||
|
||
---
|
||
|
||
## 13. 调试
|
||
|
||
- 浏览器中:`window.framework`、`window.rootVue`(根实例,在 `createApp` 创建后设置)。
|
||
- 需要未压缩源码调试时,可在业务工程里直接引用框架 **`src/index.js`**(需配置好 alias、loader 与 peer 依赖),或使用浏览器「在源映射中黑盒脚本」等能力。
|
||
|
||
---
|
||
|
||
## 14. Demo 项目
|
||
|
||
`demo/` 为示例:请先在**仓库根目录**执行 `npm run build` 生成 `dist/admin-framework.js`,再在 `demo` 目录安装依赖并执行 `npm run dev`。`demo/src/main.js` 通过相对路径引用上级 `dist` 中的 UMD 包。
|
||
|
||
---
|
||
|
||
以上为框架对外使用方式的说明;内部实现以 `src/` 源码为准。若升级版本,请同时核对 peer 依赖与本文档中的 API 是否变更。
|