a
This commit is contained in:
1517
docs/hooks使用指南.md
Normal file
1517
docs/hooks使用指南.md
Normal file
File diff suppressed because it is too large
Load Diff
516
docs/useTable与search-form兼容说明.md
Normal file
516
docs/useTable与search-form兼容说明.md
Normal file
@@ -0,0 +1,516 @@
|
||||
# useTable 与 search-form 组件兼容使用说明
|
||||
|
||||
## 概述
|
||||
|
||||
`useTable` Hook **完全兼容**自定义 `<search-form>` 组件。只需要将搜索表单的数据对象作为 `queryForm` 传入即可。
|
||||
|
||||
## 兼容原理
|
||||
|
||||
1. **`search-form` 组件**:只是一个表单包装器,接收 `model` prop 绑定到内部的 `el-form`
|
||||
2. **`useTable` Hook**:接收 `queryForm` 对象,会自动将其合并到 API 请求参数中
|
||||
3. **两者配合**:将 `search-form` 的 `model` 对象作为 `useTable` 的 `queryForm` 传入即可
|
||||
|
||||
## 改造示例
|
||||
|
||||
### 当前代码(手动管理)
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<!-- 搜索表单 -->
|
||||
<search-form
|
||||
v-show="showSearch"
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
@keyup-enter="handleFilter(search)"
|
||||
>
|
||||
<!-- 表单项 -->
|
||||
</search-form>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table :data="tableData" v-loading="tableLoading">
|
||||
<!-- 表格列 -->
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
:current="page.currentPage"
|
||||
:size="page.pageSize"
|
||||
:total="page.total"
|
||||
@currentChange="currentChange"
|
||||
@sizeChange="handleSizeChange"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const search = reactive({
|
||||
deptCode: '',
|
||||
realName: '',
|
||||
teacherNo: '',
|
||||
// ... 其他字段
|
||||
})
|
||||
|
||||
const tableData = ref([])
|
||||
const tableLoading = ref(false)
|
||||
const page = reactive({
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
})
|
||||
const params = ref<any>({})
|
||||
|
||||
// 手动实现数据加载
|
||||
const getList = (page: any) => {
|
||||
tableLoading.value = true
|
||||
fetchList(Object.assign({
|
||||
current: page.currentPage,
|
||||
size: page.pageSize
|
||||
}, params.value)).then((response: any) => {
|
||||
tableData.value = response.data.record.records
|
||||
page.total = response.data.record.total
|
||||
tableLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
// 手动实现分页
|
||||
const currentChange = (val: number) => {
|
||||
page.currentPage = val
|
||||
getList(page)
|
||||
}
|
||||
|
||||
const handleSizeChange = (val: number) => {
|
||||
page.pageSize = val
|
||||
page.currentPage = 1
|
||||
getList(page)
|
||||
}
|
||||
|
||||
// 查询
|
||||
const handleFilter = (param: any) => {
|
||||
params.value = { ...param }
|
||||
page.currentPage = 1
|
||||
getList(page)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getList(page)
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
### 改造后代码(使用 useTable)
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<!-- 搜索表单 - 保持不变 -->
|
||||
<search-form
|
||||
v-show="showSearch"
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
@keyup-enter="handleFilter(search)"
|
||||
>
|
||||
<!-- 表单项 -->
|
||||
</search-form>
|
||||
|
||||
<!-- 表格 - 使用 state.dataList 和 state.loading -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<!-- 表格列 -->
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 - 使用 state.pagination -->
|
||||
<pagination
|
||||
:current="state.pagination.current"
|
||||
:size="state.pagination.size"
|
||||
:total="state.pagination.total"
|
||||
@currentChange="currentChangeHandle"
|
||||
@sizeChange="sizeChangeHandle"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { fetchList } from '/@/api/professional/teacherbase'
|
||||
|
||||
// 搜索表单数据 - 保持不变
|
||||
const search = reactive({
|
||||
deptCode: '',
|
||||
realName: '',
|
||||
teacherNo: '',
|
||||
// ... 其他字段
|
||||
})
|
||||
|
||||
// 额外参数(如 flag 等)
|
||||
const params = ref<any>({})
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
// 将 search 对象作为 queryForm
|
||||
queryForm: search,
|
||||
|
||||
// 自定义 pageList 方法,合并额外参数
|
||||
pageList: async (queryParams: any) => {
|
||||
// 合并 search 和 params 中的额外参数
|
||||
return await fetchList({
|
||||
...queryParams,
|
||||
...params.value
|
||||
})
|
||||
},
|
||||
|
||||
// 数据属性映射(根据后端返回结构调整)
|
||||
props: {
|
||||
item: 'record.records', // 数据列表路径
|
||||
totalCount: 'record.total' // 总数字段路径
|
||||
},
|
||||
|
||||
// 数据加载完成后的回调
|
||||
onLoaded: async (state) => {
|
||||
// 数据转换逻辑
|
||||
state.dataList = convertDictData(state.dataList)
|
||||
|
||||
// 其他处理逻辑(如 auditAll)
|
||||
// ...
|
||||
}
|
||||
})
|
||||
|
||||
// 使用 useTable Hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle,
|
||||
state
|
||||
} = useTable(state)
|
||||
|
||||
// 查询方法 - 简化
|
||||
const handleFilter = (param: any) => {
|
||||
// 更新额外参数
|
||||
params.value = { ...param }
|
||||
// 调用 getDataList 刷新数据(会自动跳转到第一页)
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
searchFormRef.value?.formRef?.resetFields()
|
||||
// 重置 search 对象
|
||||
Object.keys(search).forEach(key => {
|
||||
search[key] = ''
|
||||
})
|
||||
params.value = {}
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 其他需要刷新表格的地方
|
||||
const handelQuickSeach = (val: any) => {
|
||||
params.value.flag = val
|
||||
getDataList() // 使用 getDataList 替代 getList(page)
|
||||
}
|
||||
|
||||
const updateInoutFlag = (row: any, val: any) => {
|
||||
const updateParams = {"teacherNo": row.teacherNo, "inoutFlag": val}
|
||||
messageBox.confirm('确认操作?').then(() => {
|
||||
updateInout(updateParams).then((res: any) => {
|
||||
message.success("修改成功")
|
||||
getDataList(false) // 刷新但保持当前页
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 数据转换函数(保持不变)
|
||||
const convertDictData = (records: any[]) => {
|
||||
// ... 转换逻辑
|
||||
return records
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 关键改造点
|
||||
|
||||
### 1. 导入 useTable
|
||||
|
||||
```typescript
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
```
|
||||
|
||||
### 2. 配置 state
|
||||
|
||||
```typescript
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: search, // 将 search 对象作为 queryForm
|
||||
pageList: fetchList, // 或自定义方法
|
||||
props: {
|
||||
item: 'record.records',
|
||||
totalCount: 'record.total'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### 3. 处理额外参数
|
||||
|
||||
如果查询时需要额外的参数(如 `params.value.flag`),有两种方式:
|
||||
|
||||
#### 方式一:自定义 pageList 方法(推荐)
|
||||
|
||||
```typescript
|
||||
const params = ref<any>({})
|
||||
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: search,
|
||||
pageList: async (queryParams: any) => {
|
||||
// 合并额外参数
|
||||
return await fetchList({
|
||||
...queryParams,
|
||||
...params.value // 合并额外参数
|
||||
})
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
#### 方式二:在 onLoaded 中处理
|
||||
|
||||
```typescript
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: search,
|
||||
pageList: fetchList,
|
||||
onLoaded: async (state) => {
|
||||
// 可以在这里处理数据转换等逻辑
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### 4. 替换数据引用
|
||||
|
||||
| 原代码 | 改造后 |
|
||||
|--------|--------|
|
||||
| `tableData` | `state.dataList` |
|
||||
| `tableLoading` | `state.loading` |
|
||||
| `page.currentPage` | `state.pagination.current` |
|
||||
| `page.pageSize` | `state.pagination.size` |
|
||||
| `page.total` | `state.pagination.total` |
|
||||
|
||||
### 5. 替换方法调用
|
||||
|
||||
| 原代码 | 改造后 |
|
||||
|--------|--------|
|
||||
| `getList(page)` | `getDataList()` 或 `getDataList(false)` |
|
||||
| `currentChange(val)` | `currentChangeHandle(val)` |
|
||||
| `handleSizeChange(val)` | `sizeChangeHandle(val)` |
|
||||
|
||||
### 6. 处理数据转换
|
||||
|
||||
如果需要在数据加载后进行转换,使用 `onLoaded` 回调:
|
||||
|
||||
```typescript
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: search,
|
||||
pageList: fetchList,
|
||||
onLoaded: async (state) => {
|
||||
// 字典数据转换
|
||||
state.dataList = convertDictData(state.dataList)
|
||||
|
||||
// 处理 auditAll 等逻辑
|
||||
// 注意:需要在 API 响应中获取,或通过其他方式处理
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## 完整改造示例(针对当前页面)
|
||||
|
||||
```typescript
|
||||
// 1. 导入 useTable
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
|
||||
// 2. 搜索表单数据(保持不变)
|
||||
const search = reactive({
|
||||
deptCode: '',
|
||||
secDeptCode: '',
|
||||
tied: '',
|
||||
realName: '',
|
||||
teacherNo: '',
|
||||
retireDate: '',
|
||||
pfTitleId: '',
|
||||
stationDutyLevelId: '',
|
||||
politicsStatus: '',
|
||||
teacherCate: '',
|
||||
inoutFlag: ''
|
||||
})
|
||||
|
||||
// 3. 额外参数(用于 flag 等)
|
||||
const params = ref<any>({})
|
||||
|
||||
// 4. 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: search, // 将 search 作为 queryForm
|
||||
|
||||
// 自定义 pageList,合并额外参数
|
||||
pageList: async (queryParams: any) => {
|
||||
// 合并 search 和 params
|
||||
const mergedParams = {
|
||||
...queryParams,
|
||||
...params.value,
|
||||
tied: search.tied // 如果需要特殊处理
|
||||
}
|
||||
return await fetchList(mergedParams)
|
||||
},
|
||||
|
||||
// 数据属性映射
|
||||
props: {
|
||||
item: 'record.records',
|
||||
totalCount: 'record.total'
|
||||
},
|
||||
|
||||
// 数据加载完成回调
|
||||
onLoaded: async (state) => {
|
||||
// 字典数据转换
|
||||
state.dataList = convertDictData(state.dataList)
|
||||
|
||||
// 注意:auditAll 需要从 API 响应中获取
|
||||
// 如果 API 返回在 response.data.auditAll,需要特殊处理
|
||||
}
|
||||
})
|
||||
|
||||
// 5. 使用 useTable
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle,
|
||||
state
|
||||
} = useTable(state)
|
||||
|
||||
// 6. 查询方法(简化)
|
||||
const handleFilter = (param: any) => {
|
||||
params.value = { ...param }
|
||||
getDataList() // 自动跳转到第一页
|
||||
}
|
||||
|
||||
// 7. 重置查询
|
||||
const resetQuery = () => {
|
||||
searchFormRef.value?.formRef?.resetFields()
|
||||
Object.keys(search).forEach(key => {
|
||||
search[key] = ''
|
||||
})
|
||||
params.value = {}
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 8. 快速查询
|
||||
const handelQuickSeach = (val: any) => {
|
||||
params.value.flag = val
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 9. 其他需要刷新的地方
|
||||
const updateInoutFlag = (row: any, val: any) => {
|
||||
const updateParams = {"teacherNo": row.teacherNo, "inoutFlag": val}
|
||||
messageBox.confirm('确认操作?').then(() => {
|
||||
updateInout(updateParams).then((res: any) => {
|
||||
message.success("修改成功")
|
||||
getDataList(false) // 保持当前页
|
||||
})
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
### 1. API 响应结构
|
||||
|
||||
如果 API 返回结构是 `response.data.record.records`,需要配置 `props`:
|
||||
|
||||
```typescript
|
||||
props: {
|
||||
item: 'record.records',
|
||||
totalCount: 'record.total'
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 额外参数处理
|
||||
|
||||
如果查询时需要额外的参数(不在 `search` 对象中),使用自定义 `pageList` 方法合并:
|
||||
|
||||
```typescript
|
||||
pageList: async (queryParams: any) => {
|
||||
return await fetchList({
|
||||
...queryParams,
|
||||
...params.value, // 额外参数
|
||||
// 或其他特殊参数
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 数据转换
|
||||
|
||||
如果需要在数据加载后进行转换,使用 `onLoaded` 回调:
|
||||
|
||||
```typescript
|
||||
onLoaded: async (state) => {
|
||||
state.dataList = convertDictData(state.dataList)
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 特殊响应字段
|
||||
|
||||
如果 API 响应中有特殊字段(如 `auditAll`),需要在 `onLoaded` 中处理,或者自定义 `pageList` 方法:
|
||||
|
||||
```typescript
|
||||
pageList: async (queryParams: any) => {
|
||||
const response = await fetchList({
|
||||
...queryParams,
|
||||
...params.value
|
||||
})
|
||||
|
||||
// 处理特殊字段
|
||||
if (response.data.auditAll == '0') {
|
||||
auditAll.value = false
|
||||
} else {
|
||||
auditAll.value = true
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 初始化数据加载
|
||||
|
||||
`useTable` 默认会在 `onMounted` 时自动加载数据。如果不需要自动加载,设置:
|
||||
|
||||
```typescript
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: search,
|
||||
pageList: fetchList,
|
||||
createdIsNeed: false // 禁用自动加载
|
||||
})
|
||||
|
||||
// 手动调用
|
||||
onMounted(() => {
|
||||
init()
|
||||
loadSearchDictData()
|
||||
getDataList() // 手动加载
|
||||
})
|
||||
```
|
||||
|
||||
## 优势总结
|
||||
|
||||
使用 `useTable` 后:
|
||||
|
||||
1. ✅ **代码量减少**:不需要手动管理 `tableData`、`tableLoading`、`page`
|
||||
2. ✅ **自动状态管理**:loading、分页、数据自动管理
|
||||
3. ✅ **统一方法**:`getDataList()` 统一刷新数据
|
||||
4. ✅ **兼容性好**:完全兼容自定义 `search-form` 组件
|
||||
5. ✅ **灵活扩展**:支持自定义 `pageList`、`onLoaded` 等回调
|
||||
|
||||
## 总结
|
||||
|
||||
**`useTable` 完全兼容自定义 `<search-form>` 组件**,只需要:
|
||||
|
||||
1. 将 `search` 对象作为 `queryForm` 传入
|
||||
2. 使用 `state.dataList`、`state.loading`、`state.pagination` 替代手动管理的状态
|
||||
3. 使用 `getDataList()` 替代 `getList(page)`
|
||||
4. 使用 `currentChangeHandle`、`sizeChangeHandle` 替代手动分页方法
|
||||
|
||||
如果有额外参数或特殊处理,使用自定义 `pageList` 方法或 `onLoaded` 回调即可。
|
||||
|
||||
309
docs/按钮样式规范.md
Normal file
309
docs/按钮样式规范.md
Normal file
@@ -0,0 +1,309 @@
|
||||
# 按钮样式设计规范
|
||||
|
||||
本文档定义了项目中按钮组件的样式规范,包括实心按钮和Plain按钮的使用规则,确保整个应用的按钮样式统一、协调、美观。
|
||||
|
||||
## 一、按钮类型分类
|
||||
|
||||
### 1. 实心按钮(Solid)- 用于最重要的操作
|
||||
|
||||
**使用场景:**
|
||||
- 新增、创建操作
|
||||
- 保存、提交操作
|
||||
- 确认、确定操作
|
||||
- 删除等危险操作(需要突出警示)
|
||||
|
||||
**视觉特点:**
|
||||
- 实心填充,高对比度
|
||||
- 突出显示,吸引用户注意力
|
||||
- 通常位于操作区域的主要位置
|
||||
|
||||
**代码示例:**
|
||||
```vue
|
||||
<!-- 主要操作:新增 -->
|
||||
<el-button type="primary" icon="Plus" @click="handleAdd">新 增</el-button>
|
||||
|
||||
<!-- 危险操作:删除 -->
|
||||
<el-button type="danger" icon="Delete" @click="handleDelete">删 除</el-button>
|
||||
```
|
||||
|
||||
### 2. Plain按钮(边框样式)- 用于次要操作
|
||||
|
||||
**使用场景:**
|
||||
- 查询、搜索操作
|
||||
- 导出、导入操作
|
||||
- 设置、配置操作
|
||||
- 辅助功能操作
|
||||
|
||||
**视觉特点:**
|
||||
- 边框+透明背景
|
||||
- 不抢夺视觉焦点
|
||||
- 保持页面协调统一
|
||||
- 适合批量操作按钮
|
||||
|
||||
**代码示例:**
|
||||
```vue
|
||||
<!-- 查询操作 -->
|
||||
<el-button type="primary" plain icon="Search" @click="handleSearch">查询</el-button>
|
||||
|
||||
<!-- 导出操作 -->
|
||||
<el-button type="primary" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
|
||||
<!-- 导入操作 -->
|
||||
<el-button type="primary" plain icon="Upload" @click="handleImport">导入</el-button>
|
||||
```
|
||||
|
||||
### 3. 默认按钮 - 用于中性操作
|
||||
|
||||
**使用场景:**
|
||||
- 设置、配置操作
|
||||
- 状态切换操作
|
||||
- 中性功能操作
|
||||
|
||||
**视觉特点:**
|
||||
- 灰色系,低调不突出
|
||||
- 适合不重要的操作
|
||||
|
||||
**代码示例:**
|
||||
```vue
|
||||
<!-- 设置操作 -->
|
||||
<el-button icon="Setting" @click="handleSetting">状态锁定</el-button>
|
||||
```
|
||||
|
||||
## 二、配色方案
|
||||
|
||||
> **设计原则:** 在保持项目默认样式的基础上,通过颜色区分不同操作类型,提升视觉层次和识别度。
|
||||
|
||||
### 主要操作按钮
|
||||
- **类型:** `type="primary"` 实心
|
||||
- **颜色:** 蓝色实心填充
|
||||
- **用途:** 新增、保存、提交等主要操作
|
||||
- **示例:** 新增按钮
|
||||
|
||||
### 查询操作按钮
|
||||
- **类型:** `type="primary" plain`
|
||||
- **颜色:** 蓝色边框 + 透明背景
|
||||
- **用途:** 查询、搜索、筛选等操作
|
||||
- **示例:** 一体化查询、搜索按钮
|
||||
- **说明:** 与主要操作保持同一色系,体现关联性
|
||||
|
||||
### 导出操作按钮
|
||||
- **类型:** `type="warning" plain`
|
||||
- **颜色:** 橙色边框 + 透明背景
|
||||
- **用途:** 数据导出、下载等操作
|
||||
- **示例:** 导出WORD、自定义导出
|
||||
- **说明:** 橙色表示数据输出,与导入形成对比
|
||||
|
||||
### 导入操作按钮
|
||||
- **类型:** `type="primary" plain`
|
||||
- **颜色:** 蓝色边框 + 透明背景
|
||||
- **用途:** 数据导入、上传等操作
|
||||
- **示例:** 导入信息
|
||||
- **说明:** 保持项目默认样式,与查询操作保持一致
|
||||
|
||||
### 设置操作按钮
|
||||
- **类型:** 默认样式(无type属性)
|
||||
- **颜色:** 灰色系
|
||||
- **用途:** 设置、配置、状态锁定等中性操作
|
||||
- **示例:** 状态锁定按钮
|
||||
|
||||
### 危险操作按钮
|
||||
- **类型:** `type="danger"` 实心 或 `type="danger" plain`
|
||||
- **颜色:** 红色
|
||||
- **用途:** 删除、清空等危险操作
|
||||
- **示例:** 删除按钮
|
||||
|
||||
## 三、按钮图标规范
|
||||
|
||||
所有按钮应配合相应的图标使用,提升用户体验和视觉识别度。
|
||||
|
||||
### 常用图标映射
|
||||
|
||||
| 操作类型 | 图标名称 | 说明 |
|
||||
|---------|---------|------|
|
||||
| 新增/添加 | `FolderAdd` | 文件夹加号图标(项目默认) |
|
||||
| 查询/搜索 | `Search` | 搜索图标 |
|
||||
| 导出/下载 | `Download` | 下载图标 |
|
||||
| 导入/上传 | `Upload` | 上传图标(项目默认) |
|
||||
| 编辑/修改 | `Edit` | 编辑图标 |
|
||||
| 删除 | `Delete` | 删除图标 |
|
||||
| 查看/详情 | `View` | 查看图标 |
|
||||
| 设置/配置 | `Setting` | 设置图标 |
|
||||
| 锁定/解锁 | `Lock` | 锁定图标 |
|
||||
| 刷新/重置 | `Refresh` | 刷新图标 |
|
||||
| 用户相关 | `User` | 用户图标 |
|
||||
|
||||
### 图标使用示例
|
||||
|
||||
```vue
|
||||
<el-button type="primary" icon="FolderAdd" @click="handleAdd">新 增</el-button>
|
||||
<el-button type="primary" plain icon="Search" @click="handleSearch">查询</el-button>
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
<el-button type="primary" plain icon="Upload" @click="handleImport">导入</el-button>
|
||||
```
|
||||
|
||||
## 四、按钮尺寸规范
|
||||
|
||||
### 默认尺寸(default)
|
||||
- 用于页面主要操作区域的按钮
|
||||
- 高度:32px(Element Plus默认)
|
||||
|
||||
### 小尺寸(small)
|
||||
- 用于表格操作列、对话框底部等空间受限的场景
|
||||
- 高度:24px
|
||||
- 使用 `size="small"` 属性
|
||||
|
||||
```vue
|
||||
<!-- 表格操作列 -->
|
||||
<el-button type="primary" link size="small" @click="handleEdit">编辑</el-button>
|
||||
```
|
||||
|
||||
### 链接按钮(link)
|
||||
- 用于表格操作列,节省空间
|
||||
- 使用 `link` 属性
|
||||
|
||||
```vue
|
||||
<el-button type="primary" link size="small" @click="handleView">查看</el-button>
|
||||
```
|
||||
|
||||
## 五、按钮布局规范
|
||||
|
||||
### 按钮间距
|
||||
- 按钮之间使用 `class="ml10"` 保持10px的左边距
|
||||
- 确保按钮组视觉统一
|
||||
|
||||
```vue
|
||||
<el-button type="primary" icon="FolderAdd">新 增</el-button>
|
||||
<el-button type="primary" plain icon="Search" class="ml10">查询</el-button>
|
||||
<el-button type="warning" plain icon="Download" class="ml10">导出</el-button>
|
||||
<el-button type="primary" plain icon="Upload" class="ml10">导入</el-button>
|
||||
```
|
||||
|
||||
### 按钮分组
|
||||
- 相关功能的按钮应放在一起
|
||||
- 主要操作按钮放在最前面
|
||||
- 次要操作按钮放在后面
|
||||
|
||||
## 六、完整示例
|
||||
|
||||
### 页面操作按钮组示例
|
||||
|
||||
```vue
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<!-- 主要操作:新增 -->
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd"
|
||||
v-if="permissions.add">新 增
|
||||
</el-button>
|
||||
|
||||
<!-- 查询操作:使用 primary plain 样式 -->
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="Search"
|
||||
class="ml10"
|
||||
@click="handleSearch">查询
|
||||
</el-button>
|
||||
|
||||
<!-- 导出操作:使用 warning plain 样式,橙色边框 -->
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
class="ml10"
|
||||
@click="handleExport">导出
|
||||
</el-button>
|
||||
|
||||
<!-- 导入操作:使用 primary plain 样式,蓝色边框,保持项目默认样式 -->
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="Upload"
|
||||
class="ml10"
|
||||
@click="handleImport">导入
|
||||
</el-button>
|
||||
|
||||
<!-- 设置操作:使用默认样式 -->
|
||||
<el-button
|
||||
icon="Setting"
|
||||
class="ml10"
|
||||
@click="handleSetting">设置
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
```
|
||||
|
||||
### 表格操作列示例
|
||||
|
||||
```vue
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click="handleEdit(scope.row)">编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
link
|
||||
size="small"
|
||||
@click="handleDelete(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
```
|
||||
|
||||
## 七、最佳实践
|
||||
|
||||
1. **一致性原则**
|
||||
- 相同功能的按钮在整个应用中应使用相同的样式
|
||||
- 保持图标和颜色的统一性
|
||||
|
||||
2. **层次分明**
|
||||
- 主要操作使用实心按钮,突出显示
|
||||
- 次要操作使用Plain按钮,保持协调
|
||||
|
||||
3. **语义化**
|
||||
- 按钮的颜色和样式应与其功能语义相匹配
|
||||
- 危险操作使用红色,数据操作使用绿色等
|
||||
|
||||
4. **用户体验**
|
||||
- 重要操作按钮应放在显眼位置
|
||||
- 按钮文字应简洁明了
|
||||
- 配合图标提升识别度
|
||||
|
||||
5. **响应式考虑**
|
||||
- 在移动端或小屏幕设备上,考虑使用更紧凑的布局
|
||||
- 使用 `size="small"` 适应空间限制
|
||||
|
||||
## 八、注意事项
|
||||
|
||||
1. **避免过度使用实心按钮**
|
||||
- 一个页面中实心按钮不应过多,通常1-2个主要操作即可
|
||||
- 过多的实心按钮会分散用户注意力
|
||||
|
||||
2. **Plain按钮的优势**
|
||||
- Plain按钮视觉更柔和,适合批量操作
|
||||
- 不会抢夺主要操作的视觉焦点
|
||||
|
||||
3. **图标选择**
|
||||
- 图标应与操作功能语义匹配
|
||||
- 使用Element Plus内置图标,保持一致性
|
||||
|
||||
4. **权限控制**
|
||||
- 按钮应根据用户权限显示/隐藏
|
||||
- 使用 `v-if` 控制按钮的显示
|
||||
|
||||
## 九、更新记录
|
||||
|
||||
- **2024-XX-XX**: 创建按钮样式规范文档
|
||||
- 规范版本:v1.0
|
||||
|
||||
---
|
||||
|
||||
**维护者:** 前端开发团队
|
||||
**最后更新:** 2024年
|
||||
|
||||
Reference in New Issue
Block a user