docs(guide): 完善项目开发规范和图标使用指南

文档更新:
- 更新项目名称为Coi Admin,保持品牌一致性
- 新增完整的图标使用规范和最佳实践
- 添加render函数中图标渲染的详细指导
- 提供图标语义映射表和使用示例
- 明确图标使用的强制要求和禁止行为

规范内容:
- 统一使用icon-park-outline图标库
- 模板中直接使用图标组件的正确方式
- render函数中图标组件的导入和使用规范
- 常用操作图标的语义化映射关系
- 完整的代码示例和错误示范对比
This commit is contained in:
Leo 2025-07-07 14:34:42 +08:00
parent 66fe7e6b87
commit 3d39ef37e2
2 changed files with 324 additions and 2 deletions

324
CLAUDE.md
View File

@ -32,7 +32,7 @@ DRY (Don't Repeat Yourself):绝不复制代码片段。通过抽象(如函
## 项目概述
Nova Admin 是一个基于 Vue3、Vite5、TypeScript 和 Naive UI 的简洁后台管理模板,实现了完整的认证、权限管理、路由管理等功能。
Coi Admin 是一个基于 Vue3、Vite5、TypeScript 和 Naive UI 的简洁后台管理模板,实现了完整的认证、权限管理、路由管理等功能。
## 常用命令
@ -251,6 +251,328 @@ coiMsgBox('确定要删除吗?', '删除确认').then(() => {
})
```
## 📝 图标使用规范(强制要求)
**项目中的图标使用规范,所有按钮和操作界面必须严格遵守**
### 核心原则
1. **所有按钮必须配备图标** - 提升用户体验和界面美观度
2. **图标必须语义化** - 图标含义要与按钮功能高度匹配
3. **统一的图标库** - 统一使用 `icon-park-outline` 图标库
### 图标添加方式
**✅ 正确方式:直接在模板中使用图标组件**
```vue
<template>
<!-- 基础按钮 -->
<NButton type="primary" @click="handleAdd">
<template #icon>
<NIcon>
<icon-park-outline:plus />
</NIcon>
</template>
新增
</NButton>
<!-- 条件图标显示 -->
<NButton type="primary" @click="handleAction">
<template #icon>
<NIcon>
<icon-park-outline:refresh v-if="hasSearchConditions()" />
<icon-park-outline:plus v-else />
</NIcon>
</template>
{{ actionText }}
</NButton>
<!-- 在组件插槽中使用 -->
<NovaEmpty>
<template #action>
<NButton type="primary" round>
<template #icon>
<NIcon>
<icon-park-outline:plus />
</NIcon>
</template>
新增数据
</NButton>
</template>
</NovaEmpty>
</template>
```
**❌ 错误方式:字符串传递或复杂处理**
```vue
<!-- 错误:不要通过字符串传递图标 -->
<MyComponent :icon="'icon-park-outline:plus'" />
<!-- 错误不要通过h()函数处理图标 -->
<MyComponent :icon="h('icon-park-outline:plus')" />
<!-- 错误:不要在组件内部处理字符串图标 -->
<component :is="iconString" />
```
### 常用图标语义映射
| 操作类型 | 推荐图标 | 示例场景 |
|---------|---------|---------|
| 新增/添加 | `icon-park-outline:plus` | 新增用户、添加数据 |
| 编辑/修改 | `icon-park-outline:edit` | 编辑信息、修改配置 |
| 删除 | `icon-park-outline:delete` | 删除记录、移除项目 |
| 搜索 | `icon-park-outline:search` | 搜索按钮、查询操作 |
| 刷新/重置 | `icon-park-outline:refresh` | 重置表单、刷新数据 |
| 保存 | `icon-park-outline:check` | 保存设置、确认操作 |
| 取消 | `icon-park-outline:close` | 取消操作、关闭弹框 |
| 导出 | `icon-park-outline:download` | 导出数据、下载文件 |
| 导入 | `icon-park-outline:upload` | 导入数据、上传文件 |
| 设置 | `icon-park-outline:setting` | 系统设置、配置管理 |
| 查看 | `icon-park-outline:preview-open` | 查看详情、预览内容 |
| 复制 | `icon-park-outline:copy` | 复制内容、克隆数据 |
### 图标使用要求
**1. 必须添加图标的场景**
- ✅ 所有操作按钮(新增、编辑、删除、保存等)
- ✅ 搜索和重置按钮
- ✅ 导入导出按钮
- ✅ 空状态组件的操作按钮
- ✅ 表单提交和取消按钮
**2. 图标尺寸规范**
- 默认按钮:无需指定尺寸
- 大按钮:可根据需要调整
- 小按钮:保持图标清晰可见
**3. 图标样式要求**
```vue
<template #icon>
<NIcon>
<!-- 图标组件直接使用,无需额外样式 -->
<icon-park-outline:plus />
</NIcon>
</template>
```
### 严格禁止行为
- ❌ 按钮不添加图标
- ❌ 使用字符串方式传递图标
- ❌ 在JavaScript中动态处理图标组件
- ❌ 使用其他图标库(除非特殊需求)
- ❌ 图标与功能语义不匹配
### 示例:完整的页面按钮实现
```vue
<template>
<div class="page-actions">
<!-- 主要操作按钮 -->
<NButton v-permission="PERMISSIONS.USER.ADD" type="primary" @click="handleAdd">
<template #icon>
<NIcon><icon-park-outline:plus /></NIcon>
</template>
新增
</NButton>
<!-- 批量操作按钮 -->
<NButton type="error" :disabled="selectedRows.length === 0" @click="handleBatchDelete">
<template #icon>
<NIcon><icon-park-outline:delete /></NIcon>
</template>
删除
</NButton>
<!-- 功能按钮 -->
<NButton @click="handleExport">
<template #icon>
<NIcon><icon-park-outline:download /></NIcon>
</template>
导出
</NButton>
<!-- 搜索重置按钮 -->
<NButton type="primary" @click="handleSearch">
<template #icon>
<NIcon><icon-park-outline:search /></NIcon>
</template>
搜索
</NButton>
<NButton @click="handleReset">
<template #icon>
<NIcon><icon-park-outline:refresh /></NIcon>
</template>
重置
</NButton>
</div>
</template>
```
**遵循此规范可确保项目界面的一致性和专业性!**
### 🚀 render函数中图标渲染规范强制要求
**在DataTable等组件的render函数中使用图标时必须遵循以下规范**
#### 问题背景
在render函数中不能使用模板语法 `<icon-park-outline:edit />`,必须使用正确的组件引用方式。
#### 正确的render函数图标使用方式
**✅ 步骤1导入具体的图标组件**
```typescript
// 从 ~icons 路径导入具体图标组件
import IconParkOutlineEdit from '~icons/icon-park-outline/edit'
import IconParkOutlineDelete from '~icons/icon-park-outline/delete'
import IconParkOutlineRefresh from '~icons/icon-park-outline/refresh'
import IconParkOutlineSetting from '~icons/icon-park-outline/setting'
```
**✅ 步骤2在render函数中使用组件引用**
```typescript
// 表格列定义中的正确用法
const columns: DataTableColumns<UserVo> = [
{
title: '操作',
key: 'actions',
render: (row) => {
const buttons = []
// 编辑按钮 - 正确方式
buttons.push(h(NButton, {
type: 'primary',
size: 'small',
onClick: () => handleEdit(row),
}, {
icon: () => h(NIcon, { size: 14 }, { default: () => h(IconParkOutlineEdit) }),
default: () => '编辑',
}))
// 删除按钮 - 正确方式
buttons.push(h(NButton, {
type: 'error',
size: 'small',
onClick: () => handleDelete(row),
}, {
icon: () => h(NIcon, { size: 14 }, { default: () => h(IconParkOutlineDelete) }),
default: () => '删除',
}))
return h('div', { class: 'flex gap-2' }, buttons)
}
}
]
```
**❌ 错误方式:使用字符串引用**
```typescript
// 这种方式在render函数中无效
icon: () => h(NIcon, {}, { default: () => h('icon-park-outline:edit') })
// 这种方式也无效
icon: () => h(NIcon, {}, { default: () => h('IconParkOutlineEdit') })
```
#### 常用图标的正确导入方式
```typescript
// 操作类图标
import IconParkOutlineEdit from '~icons/icon-park-outline/edit' // 编辑
import IconParkOutlineDelete from '~icons/icon-park-outline/delete' // 删除
import IconParkOutlineRefresh from '~icons/icon-park-outline/refresh' // 刷新/重置
import IconParkOutlineSetting from '~icons/icon-park-outline/setting' // 设置/分配
// 功能类图标
import IconParkOutlinePlus from '~icons/icon-park-outline/plus' // 新增
import IconParkOutlineSearch from '~icons/icon-park-outline/search' // 搜索
import IconParkOutlineDownload from '~icons/icon-park-outline/download' // 下载/导出
import IconParkOutlineUpload from '~icons/icon-park-outline/upload' // 上传/导入
import IconParkOutlinePreviewOpen from '~icons/icon-park-outline/preview-open' // 查看
```
#### 完整示例:表格操作列实现
```typescript
import { h } from 'vue'
import { NButton, NIcon, NPopconfirm } from 'naive-ui'
import IconParkOutlineEdit from '~icons/icon-park-outline/edit'
import IconParkOutlineDelete from '~icons/icon-park-outline/delete'
import IconParkOutlineSetting from '~icons/icon-park-outline/setting'
const columns: DataTableColumns<DataType> = [
{
title: '操作',
key: 'actions',
width: 280,
align: 'center',
fixed: 'right',
render: (row) => {
const buttons = []
// 编辑按钮
if (hasPermission('edit')) {
buttons.push(h(NButton, {
type: 'primary',
size: 'small',
onClick: () => handleEdit(row),
}, {
icon: () => h(NIcon, { size: 14, style: 'transform: translateY(-1px)' }, {
default: () => h(IconParkOutlineEdit)
}),
default: () => '编辑',
}))
}
// 删除按钮(带确认)
if (hasPermission('delete')) {
buttons.push(h(NPopconfirm, {
onPositiveClick: () => handleDelete(row.id),
negativeText: '取消',
positiveText: '确定',
}, {
default: () => '确定删除此项吗?',
trigger: () => h(NButton, {
type: 'error',
size: 'small',
}, {
icon: () => h(NIcon, { size: 14, style: 'transform: translateY(-1px)' }, {
default: () => h(IconParkOutlineDelete)
}),
default: () => '删除',
}),
}))
}
// 设置按钮
if (hasPermission('setting')) {
buttons.push(h(NButton, {
type: 'warning',
size: 'small',
onClick: () => handleSetting(row),
}, {
icon: () => h(NIcon, { size: 14, style: 'transform: translateY(-1px)' }, {
default: () => h(IconParkOutlineSetting)
}),
default: () => '设置',
}))
}
return h('div', { class: 'flex items-center justify-center gap-2' }, buttons)
},
},
]
```
#### 核心要点总结
1. **导入方式**:使用 `~icons/icon-park-outline/图标名` 导入具体组件
2. **组件引用**在render函数中使用 `h(IconComponent)` 而非字符串
3. **命名规范**:图标组件名采用 `IconParkOutline + 图标名(首字母大写)` 格式
4. **样式调整**:可通过 `style` 属性微调图标位置和样式
5. **尺寸设置**:通过 `NIcon``size` 属性控制图标大小
**遵循此规范确保render函数中的图标能正确显示**
## 开发注意事项
### 添加新页面

2
package-lock.json generated
View File

@ -1,5 +1,5 @@
{
"name": "nova-admin",
"name": "coi-admin",
"version": "0.9.15",
"lockfileVersion": 3,
"requires": true,