chore: 移除额外的README文档文件
- 移除CHARTS_README.md - 移除DYNAMIC_FORM_COMPONENTS_README.md - 只保留根目录README.md和charts组件README.md Co-Authored-By: Claude Sonnet <claude@anthropic.com>
This commit is contained in:
802
CHARTS_README.md
802
CHARTS_README.md
@@ -1,802 +0,0 @@
|
||||
# 图表组件开发文档
|
||||
|
||||
> 资产管理系统 - 图表组件库
|
||||
>
|
||||
> 版本: v1.0.0
|
||||
>
|
||||
> 作者: 图表组件开发组
|
||||
|
||||
## 目录
|
||||
|
||||
- [概述](#概述)
|
||||
- [安装](#安装)
|
||||
- [快速开始](#快速开始)
|
||||
- [组件文档](#组件文档)
|
||||
- [统计卡片](#统计卡片)
|
||||
- [饼图](#饼图)
|
||||
- [柱状图](#柱状图)
|
||||
- [折线图](#折线图)
|
||||
- [仪表盘](#仪表盘)
|
||||
- [漏斗图](#漏斗图)
|
||||
- [业务图表](#业务图表)
|
||||
- [Composables](#composables)
|
||||
- [工具函数](#工具函数)
|
||||
- [主题定制](#主题定制)
|
||||
- [最佳实践](#最佳实践)
|
||||
- [常见问题](#常见问题)
|
||||
|
||||
## 概述
|
||||
|
||||
本图表组件库基于 ECharts 5.x 开发,为资产管理系统提供完整的数据可视化解决方案。采用 Vue 3 Composition API + TypeScript 构建,提供良好的类型支持和开发体验。
|
||||
|
||||
### 特性
|
||||
|
||||
- 美观的青灰色系主题,与系统风格统一
|
||||
- 响应式设计,自适应不同屏幕尺寸
|
||||
- 完整的 TypeScript 类型定义
|
||||
- 丰富的交互功能(点击、悬停等)
|
||||
- 性能优化(懒加载、数据缓存)
|
||||
- 易用性(简化 API、默认配置)
|
||||
|
||||
### 组件列表
|
||||
|
||||
#### 通用图表组件
|
||||
- `BaseChart` - 基础图表组件
|
||||
- `PieChart` - 饼图/环形图
|
||||
- `BarChart` - 柱状图(横向/纵向)
|
||||
- `LineChart` - 折线图(面积图)
|
||||
- `GaugeChart` - 仪表盘
|
||||
- `FunnelChart` - 漏斗图
|
||||
|
||||
#### 统计卡片组件
|
||||
- `StatCard` - 统计卡片
|
||||
- `StatCardGroup` - 统计卡片组
|
||||
|
||||
#### 业务图表组件
|
||||
- `AssetStatusChart` - 资产状态图
|
||||
- `AssetDistributionChart` - 资产分布图
|
||||
- `AssetValueTrendChart` - 资产价值趋势图
|
||||
- `AssetUtilizationChart` - 资产利用率图
|
||||
|
||||
## 安装
|
||||
|
||||
### 依赖
|
||||
|
||||
确保项目已安装以下依赖:
|
||||
|
||||
```json
|
||||
{
|
||||
"echarts": "^5.4.3"
|
||||
}
|
||||
```
|
||||
|
||||
安装命令:
|
||||
|
||||
```bash
|
||||
npm install echarts@^5.4.3
|
||||
```
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 基础使用
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<PieChart
|
||||
:data="data"
|
||||
title="资产状态分布"
|
||||
type="doughnut"
|
||||
height="400px"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { PieChart } from '@/components/charts'
|
||||
|
||||
const data = ref([
|
||||
{ name: '库存中', value: 200 },
|
||||
{ name: '在用', value: 750 },
|
||||
{ name: '维修中', value: 50 },
|
||||
])
|
||||
</script>
|
||||
```
|
||||
|
||||
## 组件文档
|
||||
|
||||
### 统计卡片
|
||||
|
||||
#### StatCard
|
||||
|
||||
用于展示关键指标、趋势等信息。
|
||||
|
||||
**Props**
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| title | 标题 | string | - |
|
||||
| value | 数值 | number \| string | - |
|
||||
| unit | 单位 | string | - |
|
||||
| icon | 图标 | Component | - |
|
||||
| trend | 趋势方向 | 'up' \| 'down' \| 'flat' | - |
|
||||
| trendValue | 趋势值 | number | - |
|
||||
| color | 颜色 | string | '#475569' |
|
||||
| loading | 加载状态 | boolean | false |
|
||||
| clickable | 是否可点击 | boolean | false |
|
||||
|
||||
**Events**
|
||||
|
||||
| 事件名 | 说明 | 回调参数 |
|
||||
|--------|------|----------|
|
||||
| click | 点击事件 | - |
|
||||
|
||||
**示例**
|
||||
|
||||
```vue
|
||||
<StatCard
|
||||
title="资产总数"
|
||||
:value="1000"
|
||||
unit="台"
|
||||
:icon="Box"
|
||||
trend="up"
|
||||
:trend-value="12.5"
|
||||
color="#475569"
|
||||
:clickable="true"
|
||||
@click="handleClick"
|
||||
/>
|
||||
```
|
||||
|
||||
#### StatCardGroup
|
||||
|
||||
多个统计卡片的组合展示。
|
||||
|
||||
**Props**
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| items | 卡片配置数组 | StatCardConfig[] | [] |
|
||||
| colWidth | 列宽 | number | 6 |
|
||||
|
||||
**示例**
|
||||
|
||||
```vue
|
||||
<StatCardGroup :items="statCards" col-width="6 />
|
||||
```
|
||||
|
||||
### 饼图
|
||||
|
||||
#### PieChart
|
||||
|
||||
用于展示占比分布,支持饼图和环形图。
|
||||
|
||||
**Props**
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| data | 数据 | Array<{name: string, value: number}> | [] |
|
||||
| title | 标题 | string | - |
|
||||
| type | 图表类型 | 'pie' \| 'doughnut' | 'doughnut' |
|
||||
| showLegend | 是否显示图例 | boolean | true |
|
||||
| showLabel | 是否显示标签 | boolean | true |
|
||||
| height | 高度 | string | '400px' |
|
||||
| customColor | 是否使用自定义颜色 | boolean | false |
|
||||
|
||||
**Events**
|
||||
|
||||
| 事件名 | 说明 | 回调参数 |
|
||||
|--------|------|----------|
|
||||
| ready | 图表就绪 | chart: ECharts |
|
||||
| click | 点击事件 | item: 数据项 |
|
||||
|
||||
**示例**
|
||||
|
||||
```vue
|
||||
<!-- 基础环形图 -->
|
||||
<PieChart
|
||||
:data="[
|
||||
{ name: '库存中', value: 200, status: 'in_stock' },
|
||||
{ name: '在用', value: 750, status: 'in_use' }
|
||||
]"
|
||||
title="资产状态分布"
|
||||
type="doughnut"
|
||||
height="400px"
|
||||
:custom-color="true"
|
||||
@click="handleClick"
|
||||
/>
|
||||
```
|
||||
|
||||
### 柱状图
|
||||
|
||||
#### BarChart
|
||||
|
||||
用于比较数据大小,支持横向和纵向。
|
||||
|
||||
**Props**
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| data | 数据 | Array<{name: string, value: number}> | [] |
|
||||
| title | 标题 | string | - |
|
||||
| type | 方向 | 'vertical' \| 'horizontal' | 'vertical' |
|
||||
| xAxisLabel | X轴标签 | string | - |
|
||||
| yAxisLabel | Y轴标签 | string | - |
|
||||
| height | 高度 | string | '400px' |
|
||||
| showDataZoom | 是否显示数据缩放 | boolean | false |
|
||||
|
||||
**示例**
|
||||
|
||||
```vue
|
||||
<!-- 纵向柱状图 -->
|
||||
<BarChart
|
||||
:data="[
|
||||
{ name: '北京', value: 200 },
|
||||
{ name: '上海', value: 180 }
|
||||
]"
|
||||
title="资产分布统计"
|
||||
type="vertical"
|
||||
x-axis-label="机构"
|
||||
y-axis-label="数量"
|
||||
height="400px"
|
||||
/>
|
||||
|
||||
<!-- 横向柱状图 -->
|
||||
<BarChart
|
||||
:data="barData"
|
||||
type="horizontal"
|
||||
/>
|
||||
```
|
||||
|
||||
### 折线图
|
||||
|
||||
#### LineChart
|
||||
|
||||
用于展示趋势变化,支持多条折线和面积图。
|
||||
|
||||
**Props**
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| data | X轴数据 | Array<{name: string, value: number}> | [] |
|
||||
| series | 系列数据 | Array<{name: string, data: number[]}> | - |
|
||||
| title | 标题 | string | - |
|
||||
| area | 是否显示面积 | boolean | false |
|
||||
| smooth | 是否平滑曲线 | boolean | true |
|
||||
| xAxisLabel | X轴标签 | string | - |
|
||||
| yAxisLabel | Y轴标签 | string | - |
|
||||
| height | 高度 | string | '400px' |
|
||||
| showDataZoom | 是否显示数据缩放 | boolean | false |
|
||||
|
||||
**示例**
|
||||
|
||||
```vue
|
||||
<!-- 单系列折线图 -->
|
||||
<LineChart
|
||||
:data="[
|
||||
{ name: '1月', value: 850 },
|
||||
{ name: '2月', value: 920 }
|
||||
]"
|
||||
title="资产价值趋势"
|
||||
:smooth="true"
|
||||
height="400px"
|
||||
/>
|
||||
|
||||
<!-- 多系列面积图 -->
|
||||
<LineChart
|
||||
:data="dateData"
|
||||
:series="[
|
||||
{ name: '总价值', data: [850, 920, 980] },
|
||||
{ name: '净值', data: [700, 750, 800] }
|
||||
]"
|
||||
title="资产价值趋势"
|
||||
:area="true"
|
||||
:smooth="true"
|
||||
height="400px"
|
||||
/>
|
||||
```
|
||||
|
||||
### 仪表盘
|
||||
|
||||
#### GaugeChart
|
||||
|
||||
用于展示百分比、利用率等单一指标。
|
||||
|
||||
**Props**
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| value | 数值 | number | 0 |
|
||||
| min | 最小值 | number | 0 |
|
||||
| max | 最大值 | number | 100 |
|
||||
| title | 标题 | string | - |
|
||||
| unit | 单位 | string | '%' |
|
||||
| height | 高度 | string | '300px' |
|
||||
| color | 颜色分段 | string[] | - |
|
||||
| showDetail | 是否显示详情 | boolean | true |
|
||||
|
||||
**示例**
|
||||
|
||||
```vue
|
||||
<GaugeChart
|
||||
:value="75"
|
||||
:min="0"
|
||||
:max="100"
|
||||
title="资产利用率"
|
||||
unit="%"
|
||||
height="300px"
|
||||
:color="['#ef4444', '#f59e0b', '#10b981']"
|
||||
/>
|
||||
```
|
||||
|
||||
### 漏斗图
|
||||
|
||||
#### FunnelChart
|
||||
|
||||
用于展示流程、转化率等。
|
||||
|
||||
**Props**
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| data | 数据 | Array<{name: string, value: number}> | [] |
|
||||
| title | 标题 | string | - |
|
||||
| height | 高度 | string | '400px' |
|
||||
| sort | 排序方式 | 'descending' \| 'ascending' \| 'none' | 'descending' |
|
||||
|
||||
**示例**
|
||||
|
||||
```vue
|
||||
<FunnelChart
|
||||
:data="[
|
||||
{ name: '待入账', value: 100 },
|
||||
{ name: '库存中', value: 200 },
|
||||
{ name: '在用', value: 750 }
|
||||
]"
|
||||
title="资产状态流转"
|
||||
height="400px"
|
||||
/>
|
||||
```
|
||||
|
||||
### 业务图表
|
||||
|
||||
#### AssetStatusChart
|
||||
|
||||
资产状态分布图,自动使用资产状态颜色。
|
||||
|
||||
**Props**
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| data | 资产状态数据 | AssetStatusStatistics[] | [] |
|
||||
| loading | 加载状态 | boolean | false |
|
||||
|
||||
**示例**
|
||||
|
||||
```vue
|
||||
<AssetStatusChart
|
||||
:data="[
|
||||
{ status: 'in_stock', statusName: '库存中', count: 200, percentage: 20, color: '#3b82f6' },
|
||||
{ status: 'in_use', statusName: '在用', count: 750, percentage: 75, color: '#10b981' }
|
||||
]"
|
||||
@click="handleClick"
|
||||
/>
|
||||
```
|
||||
|
||||
#### AssetDistributionChart
|
||||
|
||||
资产分布图(按机构或设备类型)。
|
||||
|
||||
**Props**
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| data | 分布数据 | Array | [] |
|
||||
| type | 分布类型 | 'organization' \| 'deviceType' | 'organization' |
|
||||
| loading | 加载状态 | boolean | false |
|
||||
|
||||
**示例**
|
||||
|
||||
```vue
|
||||
<AssetDistributionChart
|
||||
:data="distributionData"
|
||||
type="organization"
|
||||
@click="handleClick"
|
||||
/>
|
||||
```
|
||||
|
||||
#### AssetValueTrendChart
|
||||
|
||||
资产价值趋势图。
|
||||
|
||||
**Props**
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| data | 趋势数据 | AssetTrendData[] | [] |
|
||||
| loading | 加载状态 | boolean | false |
|
||||
|
||||
**示例**
|
||||
|
||||
```vue
|
||||
<AssetValueTrendChart
|
||||
:data="trendData"
|
||||
@click="handleClick"
|
||||
/>
|
||||
```
|
||||
|
||||
#### AssetUtilizationChart
|
||||
|
||||
资产利用率仪表盘。
|
||||
|
||||
**Props**
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| totalAssets | 资产总数 | number | 0 |
|
||||
| usedAssets | 在用资产数 | number | 0 |
|
||||
| loading | 加载状态 | boolean | false |
|
||||
|
||||
**示例**
|
||||
|
||||
```vue
|
||||
<AssetUtilizationChart
|
||||
:total-assets="1000"
|
||||
:used-assets="750"
|
||||
/>
|
||||
```
|
||||
|
||||
## Composables
|
||||
|
||||
### useECharts
|
||||
|
||||
封装 ECharts 初始化、更新、销毁等操作。
|
||||
|
||||
**API**
|
||||
|
||||
```typescript
|
||||
const {
|
||||
chart, // 图表实例
|
||||
loading, // 加载状态
|
||||
isReady, // 是否就绪
|
||||
initChart, // 初始化图表
|
||||
setOption, // 设置配置
|
||||
showLoading, // 显示加载
|
||||
hideLoading, // 隐藏加载
|
||||
resize, // 调整尺寸
|
||||
dispose, // 销毁图表
|
||||
clear, // 清空图表
|
||||
getInstance, // 获取实例
|
||||
on, // 绑定事件
|
||||
off, // 解绑事件
|
||||
getDataURL, // 导出图片
|
||||
} = useECharts(chartRef, theme)
|
||||
```
|
||||
|
||||
**示例**
|
||||
|
||||
```typescript
|
||||
import { ref } from 'vue'
|
||||
import { useECharts } from '@/composables/useECharts'
|
||||
|
||||
const chartRef = ref<HTMLElement | null>(null)
|
||||
const { chart, setOption } = useECharts(chartRef)
|
||||
|
||||
// 设置图表配置
|
||||
setOption({
|
||||
series: [{
|
||||
type: 'pie',
|
||||
data: [...]
|
||||
}]
|
||||
})
|
||||
```
|
||||
|
||||
### useChartData
|
||||
|
||||
封装图表数据的加载、转换、缓存等操作。
|
||||
|
||||
**API**
|
||||
|
||||
```typescript
|
||||
const {
|
||||
data, // 数据
|
||||
loading, // 加载状态
|
||||
error, // 错误
|
||||
isLoaded, // 是否已加载
|
||||
hasError, // 是否有错误
|
||||
loadData, // 加载数据
|
||||
refresh, // 刷新数据
|
||||
clearCache, // 清除缓存
|
||||
setCacheExpiry, // 设置缓存过期时间
|
||||
reset, // 重置状态
|
||||
transformToChartData, // 转换数据格式
|
||||
calculatePercentages, // 计算百分比
|
||||
groupBy, // 分组聚合
|
||||
} = useChartData(apiMethod)
|
||||
```
|
||||
|
||||
**示例**
|
||||
|
||||
```typescript
|
||||
import { useChartData } from '@/composables/useChartData'
|
||||
import { getAssetStatistics } from '@/api/assets'
|
||||
|
||||
const { data, loading, loadData } = useChartData(getAssetStatistics)
|
||||
|
||||
// 加载数据
|
||||
await loadData({ type: 'status' })
|
||||
|
||||
// 刷新数据
|
||||
await refresh()
|
||||
|
||||
// 清除缓存
|
||||
clearCache()
|
||||
```
|
||||
|
||||
## 工具函数
|
||||
|
||||
### 格式化函数
|
||||
|
||||
```typescript
|
||||
import {
|
||||
formatNumber, // 格式化数值
|
||||
formatCurrency, // 格式化金额
|
||||
formatPercentage, // 格式化百分比
|
||||
getColor, // 获取图表颜色
|
||||
getAssetStatusColor, // 获取资产状态颜色
|
||||
getAssetStatusName, // 获取资产状态名称
|
||||
resizeChart, // 调整图表尺寸
|
||||
mergeOption, // 合并配置
|
||||
} from '@/utils/echarts'
|
||||
|
||||
// 格式化数值
|
||||
formatNumber(12345) // '12.35K'
|
||||
formatNumber(1234567) // '123.46万'
|
||||
|
||||
// 格式化金额
|
||||
formatCurrency(12345) // '¥12,345.00'
|
||||
formatCurrency(123456789) // '¥1.23亿'
|
||||
|
||||
// 获取资产状态颜色
|
||||
getAssetStatusColor('in_use') // '#10b981'
|
||||
getAssetStatusColor('maintenance') // '#ef4444'
|
||||
|
||||
// 获取资产状态名称
|
||||
getAssetStatusName('in_stock') // '库存中'
|
||||
getAssetStatusName('in_use') // '在用'
|
||||
```
|
||||
|
||||
### 主题配置
|
||||
|
||||
```typescript
|
||||
import {
|
||||
echartsTheme, // 主题配置
|
||||
assetStatusColors, // 资产状态颜色
|
||||
assetStatusNames, // 资产状态名称
|
||||
baseChartOption, // 基础配置
|
||||
pieChartOption, // 饼图配置
|
||||
barChartOption, // 柱状图配置
|
||||
lineChartOption, // 折线图配置
|
||||
gaugeChartOption, // 仪表盘配置
|
||||
funnelChartOption, // 漏斗图配置
|
||||
} from '@/utils/echarts'
|
||||
```
|
||||
|
||||
## 主题定制
|
||||
|
||||
### 修改主题颜色
|
||||
|
||||
编辑 `src/utils/echarts.ts` 中的 `echartsTheme`:
|
||||
|
||||
```typescript
|
||||
export const echartsTheme = {
|
||||
color: [
|
||||
'#475569', // 主色
|
||||
'#64748b',
|
||||
// ... 添加更多颜色
|
||||
],
|
||||
bgColor: '#ffffff',
|
||||
textColor: '#1e293b',
|
||||
// ... 其他配置
|
||||
}
|
||||
```
|
||||
|
||||
### 修改资产状态颜色
|
||||
|
||||
```typescript
|
||||
export const assetStatusColors: Record<string, string> = {
|
||||
pending: '#94a3b8',
|
||||
in_stock: '#3b82f6',
|
||||
in_use: '#10b981',
|
||||
// ... 修改状态颜色
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义图表主题
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<BaseChart
|
||||
:option="option"
|
||||
:theme="customTheme"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const customTheme = {
|
||||
color: ['#custom', '#colors'],
|
||||
backgroundColor: '#fff',
|
||||
// ...
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 数据加载
|
||||
|
||||
使用 `useChartData` 管理数据加载和缓存:
|
||||
|
||||
```typescript
|
||||
const { data, loading, loadData } = useChartData(fetchStatistics)
|
||||
|
||||
onMounted(() => {
|
||||
loadData({ type: 'status' })
|
||||
})
|
||||
```
|
||||
|
||||
### 2. 响应式处理
|
||||
|
||||
图表组件会自动响应窗口大小变化:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<PieChart
|
||||
:data="data"
|
||||
height="400px"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 3. 事件处理
|
||||
|
||||
```vue
|
||||
<PieChart
|
||||
:data="data"
|
||||
@click="handleChartClick"
|
||||
/>
|
||||
|
||||
<script setup lang="ts">
|
||||
const handleChartClick = (item) => {
|
||||
console.log('点击了:', item.name, item.value)
|
||||
// 跳转到详情页
|
||||
router.push(`/assets?status=${item.status}`)
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### 4. 性能优化
|
||||
|
||||
- 使用数据缓存减少请求
|
||||
- 大数据量时开启数据缩放
|
||||
- 懒加载图表组件
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<BarChart
|
||||
:data="largeData"
|
||||
:show-data-zoom="true"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// 使用缓存
|
||||
const { loadData } = useChartData(fetchData)
|
||||
await loadData(params, { useCache: true })
|
||||
</script>
|
||||
```
|
||||
|
||||
### 5. 错误处理
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
const { data, loading, error, loadData } = useChartData(fetchData)
|
||||
|
||||
try {
|
||||
await loadData()
|
||||
} catch (err) {
|
||||
ElMessage.error('加载失败: ' + err.message)
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 图表不显示?
|
||||
|
||||
A: 检查以下几点:
|
||||
1. 容器是否有高度
|
||||
2. 数据是否正确
|
||||
3. 是否有报错信息
|
||||
|
||||
### Q: 如何调整图表大小?
|
||||
|
||||
A: 设置 `height` 属性:
|
||||
|
||||
```vue
|
||||
<PieChart height="500px" />
|
||||
```
|
||||
|
||||
### Q: 如何导出图表为图片?
|
||||
|
||||
A: 使用 `getDataURL` 方法:
|
||||
|
||||
```typescript
|
||||
const { chart, getDataURL } = useECharts(chartRef)
|
||||
|
||||
const exportImage = () => {
|
||||
const url = getDataURL({ type: 'png', pixelRatio: 2 })
|
||||
// 下载图片
|
||||
}
|
||||
```
|
||||
|
||||
### Q: 如何自定义图表样式?
|
||||
|
||||
A: 有两种方式:
|
||||
|
||||
1. 使用自定义颜色
|
||||
|
||||
```vue
|
||||
<PieChart :custom-color="true" :data="data" />
|
||||
```
|
||||
|
||||
2. 修改主题配置
|
||||
|
||||
```typescript
|
||||
// src/utils/echarts.ts
|
||||
export const echartsTheme = {
|
||||
color: ['#custom', '#colors'],
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Q: 如何处理大数据量?
|
||||
|
||||
A:
|
||||
1. 开启数据缩放
|
||||
2. 使用分页加载
|
||||
3. 启用数据缓存
|
||||
|
||||
```vue
|
||||
<LineChart
|
||||
:data="data"
|
||||
:show-data-zoom="true"
|
||||
/>
|
||||
```
|
||||
|
||||
## 示例页面
|
||||
|
||||
查看完整示例:`src/views/examples/ChartsExample.vue`
|
||||
|
||||
```bash
|
||||
# 访问示例页面
|
||||
http://localhost:5173/examples/charts
|
||||
```
|
||||
|
||||
## 更新日志
|
||||
|
||||
### v1.0.0 (2025-01-24)
|
||||
|
||||
- 初始版本发布
|
||||
- 实现基础图表组件(饼图、柱状图、折线图、仪表盘、漏斗图)
|
||||
- 实现统计卡片组件
|
||||
- 实现业务图表组件
|
||||
- 提供 Composables 和工具函数
|
||||
- 完整的类型定义
|
||||
- 使用文档和示例
|
||||
|
||||
## 贡献指南
|
||||
|
||||
欢迎提交 Issue 和 Pull Request!
|
||||
|
||||
## 许可证
|
||||
|
||||
MIT
|
||||
@@ -1,475 +0,0 @@
|
||||
# 动态表单组件组使用文档
|
||||
|
||||
> **版本**: v1.0.0
|
||||
> **作者**: 动态表单组件组
|
||||
> **创建时间**: 2025-01-24
|
||||
|
||||
---
|
||||
|
||||
## 📋 目录
|
||||
|
||||
1. [组件概述](#组件概述)
|
||||
2. [核心组件](#核心组件)
|
||||
3. [字段组件](#字段组件)
|
||||
4. [工具函数](#工具函数)
|
||||
5. [Composable](#composable)
|
||||
6. [使用示例](#使用示例)
|
||||
7. [API文档](#api文档)
|
||||
8. [最佳实践](#最佳实践)
|
||||
|
||||
---
|
||||
|
||||
## 组件概述
|
||||
|
||||
动态表单组件组是资产管理系统的核心组件库,用于支持不同设备类型的自定义字段渲染和验证。
|
||||
|
||||
### 主要特性
|
||||
|
||||
- ✅ 支持多种字段类型(text、number、date、select、multiselect、boolean、textarea、tree等)
|
||||
- ✅ 动态验证规则(必填、长度、正则、自定义验证)
|
||||
- ✅ 字段联动(显示/隐藏、启用/禁用、值联动)
|
||||
- ✅ 栅格布局支持
|
||||
- ✅ 响应式设计
|
||||
- ✅ TypeScript完整类型支持
|
||||
- ✅ 统一的API接口
|
||||
|
||||
### 组件清单
|
||||
|
||||
| 组件名称 | 文件路径 | 功能说明 |
|
||||
|---------|---------|---------|
|
||||
| DynamicFieldRenderer | `@/components/form/DynamicFieldRenderer.vue` | 动态字段渲染器(核心组件) |
|
||||
| FieldDesigner | `@/components/form/FieldDesigner.vue` | 字段配置设计器 |
|
||||
| TextField | `@/components/form/fields/TextField.vue` | 单行文本输入 |
|
||||
| NumberField | `@/components/form/fields/NumberField.vue` | 数字输入 |
|
||||
| TextareaField | `@/components/form/fields/TextareaField.vue` | 多行文本输入 |
|
||||
| DateField | `@/components/form/fields/DateField.vue` | 日期选择器 |
|
||||
| SelectField | `@/components/form/fields/SelectField.vue` | 下拉选择器 |
|
||||
| MultiSelectField | `@/components/form/fields/MultiSelectField.vue` | 多选下拉 |
|
||||
| BooleanField | `@/components/form/fields/BooleanField.vue` | 开关/复选框 |
|
||||
| TreeSelect | `@/components/common/TreeSelect.vue` | 树形选择器 |
|
||||
|
||||
---
|
||||
|
||||
## 核心组件
|
||||
|
||||
### DynamicFieldRenderer 动态字段渲染器
|
||||
|
||||
最核心的组件,根据字段配置动态渲染表单。
|
||||
|
||||
#### 基础用法
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<DynamicFieldRenderer
|
||||
ref="formRef"
|
||||
v-model="formData"
|
||||
:fields="fields"
|
||||
@field-change="handleFieldChange"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import DynamicFieldRenderer from '@/components/form/DynamicFieldRenderer.vue'
|
||||
import type { FieldConfig } from '@/types/form'
|
||||
|
||||
const formRef = ref()
|
||||
const formData = ref({
|
||||
assetName: '',
|
||||
cpu: '',
|
||||
memory: ''
|
||||
})
|
||||
|
||||
const fields: FieldConfig[] = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'assetName',
|
||||
label: '资产名称',
|
||||
fieldType: 'text',
|
||||
required: true,
|
||||
span: 12
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: 'cpu',
|
||||
label: 'CPU型号',
|
||||
fieldType: 'text',
|
||||
required: true,
|
||||
span: 12
|
||||
}
|
||||
]
|
||||
</script>
|
||||
```
|
||||
|
||||
#### Props
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| modelValue | `FormData` | - | 表单数据(v-model) |
|
||||
| fields | `FieldConfig[]` | [] | 字段配置列表 |
|
||||
| readonly | `boolean` | false | 是否只读模式 |
|
||||
| labelWidth | `string \| number` | '120px' | 标签宽度 |
|
||||
| labelPosition | `'left' \| 'right' \| 'top'` | 'right' | 标签位置 |
|
||||
| gutter | `number` | 20 | 栅格间隔 |
|
||||
| dependencies | `FieldDependency[]` | [] | 字段联动配置 |
|
||||
|
||||
#### Emits
|
||||
|
||||
| 事件名 | 参数 | 说明 |
|
||||
|--------|------|------|
|
||||
| update:modelValue | `(value: FormData)` | 表单数据更新 |
|
||||
| field-change | `(event: FieldChangeEvent)` | 字段值变化 |
|
||||
| validation-change | `(state: FormValidationState)` | 验证状态变化 |
|
||||
|
||||
#### Methods
|
||||
|
||||
| 方法名 | 参数 | 返回值 | 说明 |
|
||||
|--------|------|--------|------|
|
||||
| validateField | `(fieldName: string)` | `Promise<boolean>` | 验证单个字段 |
|
||||
| validateForm | - | `Promise<boolean>` | 验证整个表单 |
|
||||
| resetForm | - | `void` | 重置表单 |
|
||||
| clearValidation | - | `void` | 清除验证 |
|
||||
| setFieldValue | `(fieldName: string, value: any)` | `void` | 设置字段值 |
|
||||
| getFieldValue | `(fieldName: string)` | `any` | 获取字段值 |
|
||||
| getFormData | - | `FormData` | 获取表单数据 |
|
||||
| setFormData | `(data: FormData)` | `void` | 设置表单数据 |
|
||||
|
||||
---
|
||||
|
||||
## 字段组件
|
||||
|
||||
### FieldConfig 字段配置
|
||||
|
||||
```typescript
|
||||
interface FieldConfig {
|
||||
id: string // 字段唯一标识
|
||||
name: string // 字段名称(用于提交)
|
||||
label: string // 字段标签(显示名称)
|
||||
fieldType: FieldType // 字段类型
|
||||
required?: boolean // 是否必填
|
||||
defaultValue?: any // 默认值
|
||||
placeholder?: string // 占位符
|
||||
options?: Array<{ // 选项(select/multiselect)
|
||||
label: string
|
||||
value: any
|
||||
disabled?: boolean
|
||||
}>
|
||||
validationRules?: { // 验证规则
|
||||
min?: number
|
||||
max?: number
|
||||
pattern?: string
|
||||
custom?: (value: any, allData: Record<string, any>) => boolean | string
|
||||
customMessage?: string
|
||||
}
|
||||
span?: number // 栅格占列数(1-24)
|
||||
visible?: boolean | ((data: Record<string, any>) => boolean) // 是否显示
|
||||
disabled?: boolean | ((data: Record<string, any>) => boolean) // 是否禁用
|
||||
description?: string // 字段描述
|
||||
className?: string // 自定义类名
|
||||
treeData?: TreeNode[] // 树形数据(tree类型)
|
||||
multiple?: boolean // 是否多选(tree类型)
|
||||
}
|
||||
```
|
||||
|
||||
### 字段类型(FieldType)
|
||||
|
||||
| 类型 | 说明 | 组件 |
|
||||
|------|------|------|
|
||||
| `text` | 单行文本 | TextField |
|
||||
| `textarea` | 多行文本 | TextareaField |
|
||||
| `number` | 数字输入 | NumberField |
|
||||
| `date` | 日期选择 | DateField |
|
||||
| `select` | 下拉选择 | SelectField |
|
||||
| `multiselect` | 多选下拉 | MultiSelectField |
|
||||
| `boolean` | 开关/复选框 | BooleanField |
|
||||
| `tree` | 树形选择 | TreeSelect |
|
||||
| `url` | URL链接 | TextField(带验证) |
|
||||
| `email` | 邮箱 | TextField(带验证) |
|
||||
| `phone` | 手机号 | TextField(带验证) |
|
||||
|
||||
---
|
||||
|
||||
## 工具函数
|
||||
|
||||
### fieldValidator 字段验证器
|
||||
|
||||
```typescript
|
||||
import { validateField, validateFields } from '@/utils/fieldValidator'
|
||||
|
||||
// 验证单个字段
|
||||
const result = validateField(value, field, allFormData)
|
||||
// 返回: { isValid: boolean, errors: string[] }
|
||||
|
||||
// 验证所有字段
|
||||
const errors = validateFields(data, fields)
|
||||
// 返回: Record<string, string[]>
|
||||
```
|
||||
|
||||
### FieldDependencyManager 字段联动管理器
|
||||
|
||||
```typescript
|
||||
import { FieldDependencyManager, DependencyConditions, DependencyActions } from '@/utils/fieldDependency'
|
||||
|
||||
const manager = new FieldDependencyManager()
|
||||
|
||||
// 添加联动配置
|
||||
manager.addDependency({
|
||||
sourceField: 'deviceType',
|
||||
targetField: 'cpu',
|
||||
type: 'show',
|
||||
condition: DependencyConditions.equals('desktop')
|
||||
})
|
||||
|
||||
// 触发联动
|
||||
const results = manager.trigger('deviceType', 'desktop', formData)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Composable
|
||||
|
||||
### useDynamicForm
|
||||
|
||||
动态表单状态管理。
|
||||
|
||||
```typescript
|
||||
import { useDynamicForm } from '@/composables/useDynamicForm'
|
||||
|
||||
const {
|
||||
formData, // 表单数据
|
||||
validationErrors, // 验证错误
|
||||
isValid, // 是否有效
|
||||
isDirty, // 是否已修改
|
||||
isSubmitting, // 是否正在提交
|
||||
setFieldValue, // 设置字段值
|
||||
validateField, // 验证字段
|
||||
validateAll, // 验证所有
|
||||
resetForm, // 重置表单
|
||||
getFormData, // 获取表单数据
|
||||
submitForm // 提交表单
|
||||
} = useDynamicForm(fields)
|
||||
```
|
||||
|
||||
### useFieldConfig
|
||||
|
||||
字段配置管理。
|
||||
|
||||
```typescript
|
||||
import { useFieldConfig } from '@/composables/useFieldConfig'
|
||||
|
||||
const {
|
||||
loadFieldConfig, // 加载字段配置
|
||||
getCachedFieldConfig, // 获取缓存配置
|
||||
clearCache // 清除缓存
|
||||
} = useFieldConfig()
|
||||
|
||||
// 加载设备类型的字段配置
|
||||
const fields = await loadFieldConfig(deviceTypeId)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 示例1:基础表单
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<DynamicFieldRenderer
|
||||
v-model="formData"
|
||||
:fields="fields"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import DynamicFieldRenderer from '@/components/form/DynamicFieldRenderer.vue'
|
||||
|
||||
const formData = ref({})
|
||||
|
||||
const fields = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'username',
|
||||
label: '用户名',
|
||||
fieldType: 'text',
|
||||
required: true,
|
||||
validationRules: {
|
||||
min: 3,
|
||||
max: 20
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: 'email',
|
||||
label: '邮箱',
|
||||
fieldType: 'email',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
</script>
|
||||
```
|
||||
|
||||
### 示例2:带字段联动
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
const fields = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'country',
|
||||
label: '国家',
|
||||
fieldType: 'select',
|
||||
options: [
|
||||
{ label: '中国', value: 'CN' },
|
||||
{ label: '美国', value: 'US' }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: 'province',
|
||||
label: '省份',
|
||||
fieldType: 'select',
|
||||
options: [], // 将通过联动动态加载
|
||||
visible: (data) => !!data.country // 选择国家后才显示
|
||||
}
|
||||
]
|
||||
|
||||
const dependencies = [
|
||||
{
|
||||
sourceField: 'country',
|
||||
targetField: 'province',
|
||||
type: 'setValue',
|
||||
condition: () => true,
|
||||
action: async (target, source) => {
|
||||
// 根据选择的国家加载省份列表
|
||||
const provinces = await loadProvinces(source)
|
||||
return provinces
|
||||
}
|
||||
}
|
||||
]
|
||||
</script>
|
||||
```
|
||||
|
||||
### 示例3:自定义验证
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
const fields = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'password',
|
||||
label: '密码',
|
||||
fieldType: 'text',
|
||||
required: true,
|
||||
validationRules: {
|
||||
custom: (value, allData) => {
|
||||
if (value.length < 8) {
|
||||
return '密码长度不能少于8位'
|
||||
}
|
||||
if (!/[A-Z]/.test(value)) {
|
||||
return '密码必须包含大写字母'
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
</script>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API文档
|
||||
|
||||
### 类型定义完整参考
|
||||
|
||||
详见 `@/types/form.ts`
|
||||
|
||||
### 常见问题
|
||||
|
||||
**Q: 如何动态加载选项?**
|
||||
|
||||
A: 使用字段联动配置的 `setValue` 类型配合异步函数:
|
||||
|
||||
```typescript
|
||||
{
|
||||
sourceField: 'category',
|
||||
targetField: 'product',
|
||||
type: 'setValue',
|
||||
condition: () => true,
|
||||
action: async () => {
|
||||
const products = await api.getProducts()
|
||||
return products
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Q: 如何实现条件验证?**
|
||||
|
||||
A: 使用 `custom` 验证函数:
|
||||
|
||||
```typescript
|
||||
validationRules: {
|
||||
custom: (value, allData) => {
|
||||
if (allData.type === 'special' && !value) {
|
||||
return '特殊类型必须填写此字段'
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 字段命名规范
|
||||
|
||||
- 使用camelCase命名:`assetName`、`purchaseDate`
|
||||
- 避免使用保留字:`name`、`id`、`value`
|
||||
- 使用语义化命名:`cpuModel` 而非 `field1`
|
||||
|
||||
### 2. 验证规则设置
|
||||
|
||||
- 必填字段始终设置 `required: true`
|
||||
- 文本字段设置合理的 `max` 限制
|
||||
- 数字字段设置 `min` 和 `max` 范围
|
||||
- 使用 `custom` 进行复杂验证
|
||||
|
||||
### 3. 字段联动设计
|
||||
|
||||
- 避免循环依赖
|
||||
- 条件函数保持简单
|
||||
- 联动动作尽可能轻量
|
||||
|
||||
### 4. 性能优化
|
||||
|
||||
- 使用字段缓存减少API请求
|
||||
- 大表单使用懒加载
|
||||
- 合理设置字段span优化布局
|
||||
|
||||
### 5. 错误处理
|
||||
|
||||
- 提供清晰的错误提示
|
||||
- 使用自定义错误消息
|
||||
- 验证失败时高亮显示错误字段
|
||||
|
||||
---
|
||||
|
||||
## 更新日志
|
||||
|
||||
### v1.0.0 (2025-01-24)
|
||||
|
||||
- ✨ 初始版本发布
|
||||
- ✨ 支持基础字段类型
|
||||
- ✨ 实现字段验证
|
||||
- ✨ 实现字段联动
|
||||
- ✨ 实现栅格布局
|
||||
- 📝 完善文档和示例
|
||||
|
||||
---
|
||||
|
||||
## 支持
|
||||
|
||||
如有问题或建议,请联系开发团队。
|
||||
Reference in New Issue
Block a user