Files
ProjectAGiPrompt/1-AgentSkills/coding-vue3-vuetify/SKILL.md
2026-02-02 15:06:28 +08:00

5.9 KiB
Raw Blame History

name, description
name description
coding-vue3-vuetify 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.tsorder.d.ts

Composition API 纯粹性

  • refreactivecomputedwatchEffect — 掌握这四大金刚
  • shallowRefreadonlytoRaw — 知道何时使用优化手段
  • 生命周期用 onMountedonUnmounted — 绝不混用 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
  • 粘性元素:筛选栏、表头 — 滚动时始终可见

数据健壮性模式

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

// 防御性访问
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 都有类型。每个边界情况都有处理。每个加载状态都很美观。这就是"生产级"的含义。