diff --git a/CLAUDE.md b/CLAUDE.md index 202cefc..4cdc19c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 + + + + + + + + + 新增 + + + + + + + + + + + {{ actionText }} + + + + + + + + + + + + 新增数据 + + + + +``` + +**❌ 错误方式:字符串传递或复杂处理** +```vue + + + + + + + + +``` + +### 常用图标语义映射 + +| 操作类型 | 推荐图标 | 示例场景 | +|---------|---------|---------| +| 新增/添加 | `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 + + + + + + +``` + +### 严格禁止行为 +- ❌ 按钮不添加图标 +- ❌ 使用字符串方式传递图标 +- ❌ 在JavaScript中动态处理图标组件 +- ❌ 使用其他图标库(除非特殊需求) +- ❌ 图标与功能语义不匹配 + +### 示例:完整的页面按钮实现 +```vue + + + + + + + + 新增 + + + + + + + + 删除 + + + + + + + + 导出 + + + + + + + + 搜索 + + + + + + + 重置 + + + +``` + +**遵循此规范可确保项目界面的一致性和专业性!** + +### 🚀 render函数中图标渲染规范(强制要求) + +**在DataTable等组件的render函数中使用图标时,必须遵循以下规范** + +#### 问题背景 +在render函数中,不能使用模板语法 ``,必须使用正确的组件引用方式。 + +#### 正确的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 = [ + { + 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 = [ + { + 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函数中的图标能正确显示!** + ## 开发注意事项 ### 添加新页面 diff --git a/package-lock.json b/package-lock.json index 85cfec3..04df5f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "nova-admin", + "name": "coi-admin", "version": "0.9.15", "lockfileVersion": 3, "requires": true,