585 lines
13 KiB
Markdown
585 lines
13 KiB
Markdown
# Admin Framework 正确使用方法
|
||
|
||
## 一、框架打包说明
|
||
|
||
Admin Framework 打包后是一个单独的 JS 文件:
|
||
- **生产版本**: `dist/admin-framework.js` (压缩,无 sourcemap)
|
||
- **开发版本**: `dist/admin-framework.dev.js` (不压缩,有 sourcemap)
|
||
|
||
## 二、在业务页面中使用框架功能
|
||
|
||
### 1. HTTP 请求
|
||
|
||
❌ **错误用法**(不要这样写):
|
||
```javascript
|
||
import http from '@/utils/admin-framework.js' // ❌ 错误!
|
||
```
|
||
|
||
✅ **正确用法**:
|
||
```javascript
|
||
// 方式一:在 Vue 组件中使用 this.$http(推荐)
|
||
export default {
|
||
async mounted() {
|
||
// GET 请求
|
||
const res = await this.$http.get('/api/users')
|
||
|
||
// POST 请求
|
||
const res2 = await this.$http.post('/api/users', { name: '张三' })
|
||
}
|
||
}
|
||
|
||
// 方式二:使用全局 framework.http
|
||
const res = await window.framework.http.get('/api/users')
|
||
```
|
||
|
||
### 2. 工具函数
|
||
|
||
✅ **正确用法**:
|
||
```javascript
|
||
export default {
|
||
methods: {
|
||
formatDate() {
|
||
// 使用 this.$tools
|
||
const formatted = this.$tools.formatDate(new Date(), 'yyyy-MM-dd')
|
||
|
||
// 或使用全局 framework.tools
|
||
const formatted2 = window.framework.tools.formatDate(new Date(), 'yyyy-MM-dd')
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3. UI 工具
|
||
|
||
✅ **正确用法**:
|
||
```javascript
|
||
export default {
|
||
methods: {
|
||
showMessage() {
|
||
// 使用 this.$uiTool
|
||
this.$uiTool.success('操作成功')
|
||
this.$uiTool.error('操作失败')
|
||
|
||
// 或使用全局 framework.uiTool
|
||
window.framework.uiTool.success('操作成功')
|
||
},
|
||
|
||
async confirmDelete() {
|
||
// 确认对话框
|
||
try {
|
||
await this.$uiTool.confirm('确定删除吗?')
|
||
// 确认后的操作
|
||
this.$Message.success('已删除')
|
||
} catch {
|
||
// 取消操作
|
||
this.$Message.info('已取消')
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4. 配置信息
|
||
|
||
✅ **正确用法**:
|
||
```javascript
|
||
export default {
|
||
data() {
|
||
return {
|
||
// 从配置中获取 API 地址
|
||
uploadUrl: this.$config.uploadUrl
|
||
}
|
||
},
|
||
|
||
mounted() {
|
||
console.log('系统标题:', this.$config.title)
|
||
console.log('API 地址:', this.$config.apiUrl)
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5. Vuex Store
|
||
|
||
✅ **正确用法**:
|
||
```javascript
|
||
import { mapGetters, mapActions } from 'vuex'
|
||
|
||
export default {
|
||
computed: {
|
||
// 使用框架内置的 store
|
||
...mapGetters('user', ['userName', 'menuList']),
|
||
...mapGetters('app', ['sysFormModel'])
|
||
},
|
||
|
||
methods: {
|
||
...mapActions('user', ['handleLogOut'])
|
||
}
|
||
}
|
||
```
|
||
|
||
### 6. 路由跳转
|
||
|
||
✅ **正确用法**:
|
||
```javascript
|
||
export default {
|
||
methods: {
|
||
goToPage() {
|
||
// 使用 path 跳转(推荐)
|
||
this.$router.push({ path: '/ball/games' })
|
||
|
||
// 带参数跳转
|
||
this.$router.push({
|
||
path: '/ball/game_comments',
|
||
query: { id: 123 }
|
||
})
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 三、创建业务 API 模块
|
||
|
||
### 正确的 API 封装方式
|
||
|
||
```javascript
|
||
// src/api/ball/gamesServer.js
|
||
|
||
/**
|
||
* 球赛管理 API
|
||
* 注意:不需要 import http,直接使用 window.framework.http
|
||
*/
|
||
|
||
class GamesServer {
|
||
/**
|
||
* 获取球赛列表
|
||
*/
|
||
async getList(params) {
|
||
return await window.framework.http.post('/games/page', params)
|
||
}
|
||
|
||
/**
|
||
* 获取球赛详情
|
||
*/
|
||
async getDetail(id) {
|
||
return await window.framework.http.get(`/games/detail/${id}`)
|
||
}
|
||
|
||
/**
|
||
* 创建球赛
|
||
*/
|
||
async create(data) {
|
||
return await window.framework.http.post('/games/create', data)
|
||
}
|
||
|
||
/**
|
||
* 更新球赛
|
||
*/
|
||
async update(id, data) {
|
||
return await window.framework.http.post(`/games/update/${id}`, data)
|
||
}
|
||
|
||
/**
|
||
* 删除球赛
|
||
*/
|
||
async delete(id) {
|
||
return await window.framework.http.post(`/games/delete/${id}`)
|
||
}
|
||
|
||
/**
|
||
* 批量删除
|
||
*/
|
||
async batchDelete(ids) {
|
||
return await window.framework.http.post('/games/batch_delete', { ids })
|
||
}
|
||
}
|
||
|
||
export default new GamesServer()
|
||
```
|
||
|
||
### 在组件中使用 API
|
||
|
||
```vue
|
||
<template>
|
||
<div>
|
||
<Tables
|
||
:columns="columns"
|
||
:data="tableData"
|
||
:loading="loading"
|
||
@on-refresh="getList"
|
||
/>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
// 导入 API 模块
|
||
import gamesServer from '@/api/ball/gamesServer.js'
|
||
|
||
export default {
|
||
name: 'Games',
|
||
data() {
|
||
return {
|
||
columns: [
|
||
{ title: 'ID', key: 'id' },
|
||
{ title: '名称', key: 'name' },
|
||
{ title: '时间', key: 'time' }
|
||
],
|
||
tableData: [],
|
||
loading: false,
|
||
queryParams: {
|
||
page: 1,
|
||
size: 20
|
||
}
|
||
}
|
||
},
|
||
|
||
mounted() {
|
||
this.getList()
|
||
},
|
||
|
||
methods: {
|
||
async getList() {
|
||
this.loading = true
|
||
try {
|
||
const res = await gamesServer.getList(this.queryParams)
|
||
if (res.code === 0) {
|
||
this.tableData = res.data.list
|
||
}
|
||
} catch (error) {
|
||
this.$uiTool.error('获取数据失败')
|
||
} finally {
|
||
this.loading = false
|
||
}
|
||
},
|
||
|
||
async handleDelete(id) {
|
||
try {
|
||
await this.$uiTool.confirm('确定删除吗?')
|
||
const res = await gamesServer.delete(id)
|
||
if (res.code === 0) {
|
||
this.$uiTool.success('删除成功')
|
||
this.getList()
|
||
}
|
||
} catch (error) {
|
||
// 取消删除
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
|
||
## 四、完整的页面示例
|
||
|
||
```vue
|
||
<template>
|
||
<div class="page-container">
|
||
<Card>
|
||
<p slot="title">
|
||
<Icon type="ios-list" />
|
||
球赛管理
|
||
</p>
|
||
|
||
<!-- 搜索栏 -->
|
||
<Form inline style="margin-bottom: 16px;">
|
||
<FormItem>
|
||
<Input
|
||
v-model="queryParams.keyword"
|
||
placeholder="请输入关键词"
|
||
clearable
|
||
style="width: 200px;"
|
||
/>
|
||
</FormItem>
|
||
<FormItem>
|
||
<Button type="primary" @click="handleSearch">
|
||
<Icon type="ios-search" />
|
||
搜索
|
||
</Button>
|
||
<Button @click="handleReset" style="margin-left: 8px;">
|
||
重置
|
||
</Button>
|
||
<Button type="success" @click="handleAdd" style="margin-left: 8px;">
|
||
<Icon type="ios-add" />
|
||
新增
|
||
</Button>
|
||
</FormItem>
|
||
</Form>
|
||
|
||
<!-- 数据表格 -->
|
||
<Tables
|
||
ref="table"
|
||
:columns="columns"
|
||
:data="tableData"
|
||
:loading="loading"
|
||
:total="total"
|
||
:page-size="queryParams.size"
|
||
:current-page="queryParams.page"
|
||
@on-page-change="handlePageChange"
|
||
@on-page-size-change="handlePageSizeChange"
|
||
/>
|
||
</Card>
|
||
|
||
<!-- 编辑弹窗 -->
|
||
<Modal
|
||
v-model="modalVisible"
|
||
:title="modalTitle"
|
||
width="600"
|
||
@on-ok="handleSubmit"
|
||
@on-cancel="handleCancel"
|
||
>
|
||
<Form ref="form" :model="formData" :rules="rules" :label-width="100">
|
||
<FormItem label="名称" prop="name">
|
||
<Input v-model="formData.name" placeholder="请输入名称" />
|
||
</FormItem>
|
||
<FormItem label="时间" prop="time">
|
||
<DatePicker
|
||
v-model="formData.time"
|
||
type="datetime"
|
||
placeholder="请选择时间"
|
||
style="width: 100%;"
|
||
/>
|
||
</FormItem>
|
||
</Form>
|
||
</Modal>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import gamesServer from '@/api/ball/gamesServer.js'
|
||
|
||
export default {
|
||
name: 'Games',
|
||
data() {
|
||
return {
|
||
// 查询参数
|
||
queryParams: {
|
||
page: 1,
|
||
size: 20,
|
||
keyword: ''
|
||
},
|
||
|
||
// 表格数据
|
||
columns: [
|
||
{ title: 'ID', key: 'id', width: 80 },
|
||
{ title: '名称', key: 'name' },
|
||
{
|
||
title: '时间',
|
||
key: 'time',
|
||
render: (h, params) => {
|
||
return h('span', this.$tools.formatDate(params.row.time, 'yyyy-MM-dd HH:mm'))
|
||
}
|
||
},
|
||
{
|
||
title: '操作',
|
||
width: 200,
|
||
render: (h, params) => {
|
||
return h('div', [
|
||
h('Button', {
|
||
props: { type: 'primary', size: 'small' },
|
||
style: { marginRight: '5px' },
|
||
on: { click: () => this.handleEdit(params.row) }
|
||
}, '编辑'),
|
||
h('Button', {
|
||
props: { type: 'error', size: 'small' },
|
||
on: { click: () => this.handleDelete(params.row.id) }
|
||
}, '删除')
|
||
])
|
||
}
|
||
}
|
||
],
|
||
tableData: [],
|
||
total: 0,
|
||
loading: false,
|
||
|
||
// 弹窗相关
|
||
modalVisible: false,
|
||
modalTitle: '新增',
|
||
formData: {
|
||
name: '',
|
||
time: ''
|
||
},
|
||
rules: {
|
||
name: [
|
||
{ required: true, message: '请输入名称', trigger: 'blur' }
|
||
],
|
||
time: [
|
||
{ required: true, type: 'date', message: '请选择时间', trigger: 'change' }
|
||
]
|
||
}
|
||
}
|
||
},
|
||
|
||
mounted() {
|
||
this.getList()
|
||
},
|
||
|
||
methods: {
|
||
// 获取列表
|
||
async getList() {
|
||
this.loading = true
|
||
try {
|
||
const res = await gamesServer.getList(this.queryParams)
|
||
if (res.code === 0) {
|
||
this.tableData = res.data.list
|
||
this.total = res.data.total
|
||
} else {
|
||
this.$uiTool.error(res.message || '获取数据失败')
|
||
}
|
||
} catch (error) {
|
||
this.$uiTool.error('获取数据失败')
|
||
} finally {
|
||
this.loading = false
|
||
}
|
||
},
|
||
|
||
// 搜索
|
||
handleSearch() {
|
||
this.queryParams.page = 1
|
||
this.getList()
|
||
},
|
||
|
||
// 重置
|
||
handleReset() {
|
||
this.queryParams = {
|
||
page: 1,
|
||
size: 20,
|
||
keyword: ''
|
||
}
|
||
this.getList()
|
||
},
|
||
|
||
// 新增
|
||
handleAdd() {
|
||
this.modalTitle = '新增'
|
||
this.formData = {
|
||
name: '',
|
||
time: ''
|
||
}
|
||
this.modalVisible = true
|
||
},
|
||
|
||
// 编辑
|
||
handleEdit(row) {
|
||
this.modalTitle = '编辑'
|
||
this.formData = { ...row }
|
||
this.modalVisible = true
|
||
},
|
||
|
||
// 删除
|
||
async handleDelete(id) {
|
||
try {
|
||
await this.$uiTool.confirm('确定删除吗?')
|
||
const res = await gamesServer.delete(id)
|
||
if (res.code === 0) {
|
||
this.$uiTool.success('删除成功')
|
||
this.getList()
|
||
} else {
|
||
this.$uiTool.error(res.message || '删除失败')
|
||
}
|
||
} catch (error) {
|
||
// 取消删除
|
||
}
|
||
},
|
||
|
||
// 提交表单
|
||
handleSubmit() {
|
||
this.$refs.form.validate(async (valid) => {
|
||
if (valid) {
|
||
try {
|
||
const res = this.formData.id
|
||
? await gamesServer.update(this.formData.id, this.formData)
|
||
: await gamesServer.create(this.formData)
|
||
|
||
if (res.code === 0) {
|
||
this.$uiTool.success('操作成功')
|
||
this.modalVisible = false
|
||
this.getList()
|
||
} else {
|
||
this.$uiTool.error(res.message || '操作失败')
|
||
}
|
||
} catch (error) {
|
||
this.$uiTool.error('操作失败')
|
||
}
|
||
}
|
||
})
|
||
},
|
||
|
||
// 取消
|
||
handleCancel() {
|
||
this.$refs.form.resetFields()
|
||
},
|
||
|
||
// 分页
|
||
handlePageChange(page) {
|
||
this.queryParams.page = page
|
||
this.getList()
|
||
},
|
||
|
||
handlePageSizeChange(size) {
|
||
this.queryParams.size = size
|
||
this.queryParams.page = 1
|
||
this.getList()
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.page-container {
|
||
padding: 20px;
|
||
}
|
||
</style>
|
||
```
|
||
|
||
## 五、全局可用的对象
|
||
|
||
在任何 Vue 组件中,都可以使用以下对象:
|
||
|
||
| 对象 | 说明 | 使用示例 |
|
||
|-----|------|---------|
|
||
| `this.$http` | HTTP 请求实例 | `this.$http.get('/api/users')` |
|
||
| `this.$tools` | 工具函数集合 | `this.$tools.formatDate(new Date())` |
|
||
| `this.$uiTool` | UI 工具函数 | `this.$uiTool.success('成功')` |
|
||
| `this.$config` | 配置对象 | `this.$config.apiUrl` |
|
||
| `this.$router` | 路由实例 | `this.$router.push({ path: '/home' })` |
|
||
| `this.$store` | Vuex Store | `this.$store.state.user.userName` |
|
||
| `window.framework` | 框架实例 | `window.framework.version` |
|
||
| `window.app` | Vue 根实例 | `window.app.$router` |
|
||
|
||
## 六、注意事项
|
||
|
||
1. ❌ **不要尝试导入框架内部模块**
|
||
```javascript
|
||
import http from '@/utils/admin-framework.js' // ❌ 错误
|
||
import tools from 'admin-framework/tools' // ❌ 错误
|
||
```
|
||
|
||
2. ✅ **使用 Vue 实例上的属性**
|
||
```javascript
|
||
this.$http // ✅ 正确
|
||
this.$tools // ✅ 正确
|
||
this.$uiTool // ✅ 正确
|
||
```
|
||
|
||
3. ✅ **或使用全局对象**
|
||
```javascript
|
||
window.framework.http // ✅ 正确
|
||
window.framework.tools // ✅ 正确
|
||
window.framework.uiTool // ✅ 正确
|
||
```
|
||
|
||
4. **路由跳转使用 path 而不是 name**
|
||
```javascript
|
||
this.$router.push({ path: '/ball/games' }) // ✅ 正确
|
||
this.$router.push({ name: '球赛管理' }) // ❌ 错误(name 可能不存在)
|
||
```
|
||
|
||
## 七、快速开始检查清单
|
||
|
||
- [ ] 框架已构建:`npm run build`
|
||
- [ ] Demo 依赖已安装:`cd demo && npm install`
|
||
- [ ] 组件映射表已配置:`demo/src/router/component-map.js`
|
||
- [ ] API 地址已配置:`demo/src/main.js` 中的 `config.apiUrl`
|
||
- [ ] 页面中使用 `this.$http` 而不是 `import http`
|
||
- [ ] 路由跳转使用 `path` 而不是 `name`
|
||
|