技术栈
- 框架: Nuxt 4, Vue 3.5, TypeScript 6
- UI: Nuxt UI v4(Reka UI + Tailwind CSS v4),Dashboard 系列组件(UDashboardPanel, UDashboardNavbar, UDashboardSidebar, UDashboardSearch, UDashboardToolbar)
- 表格: @tanstack/table-core,UTable 集成排序/筛选/分页/行选择
- 工具库: @vueuse/core(createSharedComposable, useBreakpoints), date-fns, scule, zod
- 图表: @unovis/vue(仅客户端渲染,见 HomeChart.client.vue / HomeChart.server.vue)
Nuxt UI v4 核心规范
- 必须 在
app.vue和error.vue中使用<UApp>包裹页面 - 禁止 使用 Tailwind 原生色名(
red,green,gray),必须 使用语义化别名:primary,secondary,success,info,warning,error,neutral - 弹窗统一用
v-model:open,内容放#body插槽 - 自定义组件样式在
app.config.ts中用slots和defaultVariants配置 - Dashboard 页面必须 用
<UDashboardPanel>包裹,<template #header>放<UDashboardNavbar>,<template #body>放页面内容
编码规范
核心架构:Composable + 三类数据
"一个视图组件对应一个逻辑 Composable",强制分离逻辑与视图。
在 Composable 中用 reactive() 声明三类数据:
| 前缀 | 用途 | 特点 |
|---|---|---|
pageStaticData |
静态/配置数据 | 页面生命周期内不变:字典项、常量 |
pageStatusData |
状态/响应式数据 | 驱动视图:loading、tableData、errorMsg |
pageSubmitData |
提交数据 | 与接口契约严格一致 |
必须 暴露 initPage() 作为初始化和重置入口:
typescript
async function initPage() {
_initStaticData(); _initStatusData(); _initSubmitData()
await fetchTableData()
}
函数规范
- 最少代码原则:用最少的代码实现功能,不写一行多余的代码。
- 避免 watch / computed :尽量用函数直接返回值替代
computed,用事件回调替代watch,减少响应式链路复杂度。 - 公共函数 :暴露给组件,包含副作用。私有函数 :
_开头,纯函数,无副作用。 - 复杂逻辑遵循 校验 → 处理 → 提交 三步。
- 特例:仅完全静态无交互的纯展示页才可把 script 直接写在 .vue 中。
命名约定
- 组件: PascalCase;Composable:
use开头与组件同名;文件/目录: kebab-case - 变量: camelCase;私有函数:
_开头;类型/接口: PascalCase
组件规范
.vue只负责模板结构、样式绑定、事件绑定、UI 状态展示。- 拆分:单组件 ≤300 行,>3 个
v-if分支拆子组件,重复 UI 块抽取。 - 通信:父传子
defineProps,子传父defineEmits(事件 kebab-case),跨层级 Pinia 或 provide/inject。 - 禁止 :直接修改 props、使用
$refs操作子组件。
TypeScript
- 必须
import type导入纯类型。类型不 被 Nuxt 自动导入,需显式 import,使用~/types别名 - 严禁
any、as强制断言(API 响应转换除外)
错误处理模式
- 私有函数 :只调 API,throw 向上传递。公共函数 :try-catch,转为友好信息写入
pageStatusData.errorMsg。 - 错误信息对用户友好,不直接展示技术错误。
API 对接
- 所有业务 API 通过
useAPI()访问后端http://localhost:48080/admin-api/ - 后端响应统一格式:
{ code: 0, data: ..., msg: ... },code === 0 || 200表示成功 server/api/目录保留原有 mock 端点(模板页面使用),与后端 API 互不冲突- 数据变更后需调用
refresh()刷新关联数据
Git 提交
text
<type>(<scope>): <subject>
类型: feat / fix / refactor / style / docs / chore