---
name: frontend-vue3-vuetify
description: Build production-grade Vue 3 + TypeScript + Vuetify 3 interfaces with architectural rigor. 构建生产级 Vue 3 + TypeScript + Vuetify 3 界面。Use when creating Vue components, pages, layouts, Pinia stores, or API modules. 用于创建 Vue 组件、页面、布局、Pinia 状态管理或 API 模块。Enforces strict typing, Composition API patterns, Material Design 3 aesthetics, and bulletproof data handling.
---

本技能指导构建架构严谨、类型安全、视觉精致的 Vue 3 + Vuetify 3 代码。每个组件都应该达到生产级代码库的标准——让资深工程师也引以为傲。

用户输入：$ARGUMENTS（组件规格、页面需求、功能请求或架构问题）

## 架构思维

动手写代码之前，先建立清晰认知：

- **组件身份**：这是页面(Page)、布局(Layout)、可复用组件(Component)、组合式函数(Composable)、状态仓库(Store)，还是 API 模块？每种都有独特模式。
- **数据重力**：状态住在哪里？Props 向下流动，Events 向上冒泡。跨组件状态用 Pinia。深层级传递用 `provide/inject`。
- **滚动策略**：哪个容器拥有滚动权？永远不是 body。必须显式声明。必须可控。
- **失败模式**：数据为 `null` 时怎么办？空数组？网络超时？先为不幸路径设计。

**关键原则**：生产代码预判混乱。为一切加类型。为一切加守卫。让一切优雅降级。

## 核心信条

### TypeScript 绝对主义
- `<script setup lang="ts">` — 唯一可接受的写法
- `any` 被禁止 — 使用 `unknown` + 类型守卫、泛型、工具类型
- 每个 prop、emit、ref、API 响应都必须穿戴类型
- 类型定义放在 `@/types/`，按领域组织：`user.d.ts`、`order.d.ts`

### Composition API 纯粹性
- `ref`、`reactive`、`computed`、`watchEffect` — 掌握这四大金刚
- `shallowRef`、`readonly`、`toRaw` — 知道何时使用优化手段
- 生命周期用 `onMounted`、`onUnmounted` — 绝不混用 Options API
- Pinia stores：类型化的 state、类型化的 getters、类型化的 actions — 无例外

### Vuetify 3 + Material Design 3
- 所有 UI 通过 Vuetify 组件实现 — UI 元素不使用原生 HTML
- 始终主题感知 — `rgb(var(--v-theme-surface))`，绝不 `#ffffff`
- `useDisplay()` 处理响应式逻辑 — 断点是一等公民
- 密度很重要 — 数据密集界面使用 `density="compact"`

### 布局哲学
```
┌─────────────────────────────────┐
│  工具栏 (flex-shrink-0)          │
├─────────────────────────────────┤
│                                 │
│  内容区域                        │
│  (flex-grow-1, overflow-y-auto) │
│  (min-height: 0) ← 关键！        │
│                                 │
├─────────────────────────────────┤
│  底部栏 (flex-shrink-0)          │
└─────────────────────────────────┘
```
- **禁止 body 滚动** — 视口锁定，内容在容器中滚动
- **Flexbox 陷阱**：`flex-grow-1` 子元素必须有 `min-height: 0`
- **粘性元素**：筛选栏、表头 — 滚动时始终可见

## 数据健壮性模式

将所有外部数据视为不可信：

```typescript
// 防御性访问
const userName = user?.profile?.name ?? '未知'

// 数组安全检查
const items = Array.isArray(response.data) ? response.data : []

// 模板中的存在性守卫
<template v-if="user">{{ user.name }}</template>
<v-empty-state v-else />
```

## UI 状态三位一体

每个数据驱动视图必须处理三种状态：

| 状态 | 组件 | 禁止行为 |
|------|------|----------|
| **加载中** | `v-skeleton-loader` | 显示过期数据或空白屏幕 |
| **空数据** | `v-empty-state` + 操作按钮 | 留下白茫茫一片 |
| **错误** | Snackbar + 重试选项 | 静默失败 |

## 表格与列表戒律

- 每个 `v-data-table` 都要 `fixed-header` — 没有商量余地
- 截断文本必须配 `v-tooltip` — 用户有权 hover 看到完整内容
- 100+ 条数据？用 `v-virtual-scroll` — DOM 节点数保持恒定
- 列宽显式指定 — 不玩布局抽奖

## 反模式（绝不允许）

- TypeScript 项目中出现 `.js` 文件
- 没有正当理由使用 `any`
- 硬编码颜色：`color="#1976d2"` → 应该用 `color="primary"`
- SPA 布局中出现 body 级滚动
- 表格没有固定表头
- 截断文本没有 tooltip
- 空状态真的"空空如也"
- 加载状态冻结 UI
- API 调用没有错误处理

## 参考文件

需要实现细节时查阅：

| 需求 | 文件 |
|------|------|
| 高级 TypeScript 模式 | `reference/typescript-rules.md` |
| 复杂布局结构 | `reference/layout-patterns.md` |
| API 客户端架构 | `reference/api-patterns.md` |
| 表格、列表、表单、反馈 | `reference/ui-interaction.md` |

## 项目结构

```
src/
├── api/          # Axios 实例 + 模块
├── components/   # 共享组件
├── composables/  # 可复用 hooks
├── layouts/      # 页面外壳
├── pages/        # 路由视图
├── plugins/      # Vuetify, Pinia, Router
├── store/        # Pinia stores
├── styles/       # 全局 SCSS
├── types/        # 类型定义
└── utils/        # 纯函数
```

## 输出规范

1. 陈述架构方案（2-3 句话）
2. 列出要创建的文件及其用途
3. 完整实现每个文件 — 无占位符，无 TODO
4. 对照反模式清单验证
5. 指出任何假设或权衡取舍

---

记住：你不是在写"能跑的代码"。你是在写能跑、能扩展、能维护、能令人愉悦的代码。每个 `ref` 都有类型。每个边界情况都有处理。每个加载状态都很美观。这就是"生产级"的含义。
