【自学AI】02 AI Agent Skills 深度解析(下):前端开发实战指南
前言:从理论到实践
上篇讲了 Skills 的概念和架构,这篇我们动手实践。
作为前端开发者,我会聚焦在前端相关的 Skills 上,包括:
- 如何使用 Skills(Claude Code + VS Code)
- 如何编写 Skills(以 vue-skills 为例)
- 深度拆解 vue-skills 的设计
- 2 个完整的实战案例
第一部分:Skills 使用教程
1.1 在 Claude Code 中使用 Skills
安装 Claude Code:
# macOS / Linuxcurl -fsSL https://code.claude.com/install.sh | sh
# Windows (PowerShell)irm https://code.claude.com/install.ps1 | iex
# 验证安装claude --version安装 Skills:
# 创建工作目录mkdir ~/claude-workspacecd ~/claude-workspace
# 克隆 vue-skillsgit clone https://github.com/vuejs-ai/skills.git .claude/skills/vue-skills
# 启动 Claude Codeclaude使用 Skills:
> 帮我写一个用户列表组件,要符合 Vue 3 最佳实践Claude Code 会自动调用 vue-skills,生成符合规范的代码。
1.2 在 VS Code 中使用 Skills
安装 Cursor 或 Cline 插件:
Cursor 和 Cline 都支持 Skills,推荐使用 Cline(开源免费)。
配置 Skills 目录:
在项目根目录创建 .skills/ 目录:
mkdir .skillscd .skillsgit clone https://github.com/vuejs-ai/skills.git vue-skills使用:
在 VS Code 中打开 Cline 面板,输入:
> 用 vue-skills 帮我写一个表单组件Cline 会自动加载 vue-skills 并生成代码。
第二部分:如何编写 Skills
2.1 vue-skills 的目录结构
vue-skills/├── SKILL.md # 核心指令├── composition-api.md # Composition API 规范├── reactivity.md # 响应式系统规范├── vueuse.md # VueUse 最佳实践└── references/ └── vue3-migration-guide.md # Vue 3 迁移指南为什么这样设计?
- SKILL.md 作为入口:简洁明了,< 500 行
- 按主题拆分子文档:避免单个文件过长
- references/ 放详细文档:按需加载
2.2 SKILL.md 的结构
---name: vue-skillsdescription: | Vue 3 开发最佳实践。当需要编写或审查 Vue 组件时使用。
触发条件: - 用户说"写 Vue 组件" - 用户说"审查 Vue 代码" - 用户说"优化 Vue 组件"---
# Vue 3 开发最佳实践
## 核心规则
### 1. 必须使用 Composition API详见 composition-api.md
### 2. 响应式数据规范详见 reactivity.md
### 3. 优先使用 VueUse详见 vueuse.md
## 快速检查清单
- [ ] 使用 `<script setup>` 语法- [ ] Props 和 Emits 有完整的 TypeScript 类型- [ ] 优先使用 VueUse 组合式函数- [ ] 避免解构 reactive 对象- [ ] ref 的 .value 使用正确关键点:
- description 要清晰触发条件:让 AI 知道什么时候该用
- 核心规则简洁明了:详细内容放子文档
- 快速检查清单:方便 AI 快速验证
2.3 子文档的设计
composition-api.md:
# Composition API 规范
## 必须使用 `<script setup>`
❌ 错误:\`\`\`vue<script>export default { data() { return { count: 0 } }}</script>\`\`\`
✅ 正确:\`\`\`vue<script setup lang="ts">import { ref } from 'vue'const count = ref(0)</script>\`\`\`
## Props 和 Emits 定义
✅ 正确:\`\`\`vue<script setup lang="ts">interface Props { title: string count?: number}
const props = defineProps<Props>()
interface Emits { (e: 'update', value: number): void}
const emit = defineEmits<Emits>()</script>\`\`\`为什么用示例而非说教?
因为 AI 更容易理解具体的代码示例,而不是抽象的描述。
2.4 与其他前端 Skills 的对比
vue-skills vs react-skills:
| 维度 | vue-skills | react-skills |
|---|---|---|
| 核心关注 | Composition API、响应式 | Hooks、性能优化 |
| 文档结构 | 按主题拆分(composition-api.md、reactivity.md) | 按规则分级(CRITICAL、IMPORTANT、NICE_TO_HAVE) |
| 示例风格 | ❌/✅ 对比 | Before/After 对比 |
共同点:
- 都用 TypeScript
- 都强调最佳实践
- 都提供完整的代码示例
差异点:
- vue-skills 更关注响应式陷阱
- react-skills 更关注性能优化
第三部分:深度拆解 vue-skills
3.1 响应式系统的 5 个陷阱
陷阱 1:解构 reactive 对象
// ❌ 错误:失去响应性const state = reactive({ count: 0 })const { count } = statecount++ // 不会触发更新
// ✅ 正确:使用 toRefsconst state = reactive({ count: 0 })const { count } = toRefs(state)count.value++ // 触发更新陷阱 2:ref 的 .value
// ❌ 错误:忘记 .valueconst count = ref(0)console.log(count) // RefImpl 对象
// ✅ 正确:使用 .valueconst count = ref(0)console.log(count.value) // 0陷阱 3:reactive 数组的直接赋值
// ❌ 错误:失去响应性const list = reactive([1, 2, 3])list = [4, 5, 6] // 失去响应性
// ✅ 正确:使用数组方法const list = reactive([1, 2, 3])list.splice(0, list.length, 4, 5, 6)陷阱 4:watch 的深度监听
// ❌ 错误:无法监听到变化const state = reactive({ nested: { count: 0 } })watch(() => state.nested, () => { console.log('changed')}) // 不会触发
// ✅ 正确:使用 deep 选项watch(() => state.nested, () => { console.log('changed')}, { deep: true })陷阱 5:computed 的副作用
// ❌ 错误:在 computed 中修改状态const count = ref(0)const doubled = computed(() => { count.value++ // 副作用! return count.value * 2})
// ✅ 正确:computed 只做计算const count = ref(0)const doubled = computed(() => count.value * 2)vue-skills 的价值:
把这些陷阱写进 Skill,AI 就会自动避免这些问题。
3.2 VueUse 最佳实践
原则:优先使用 VueUse,避免重复造轮子
场景 1:LocalStorage
// ❌ 错误:手动实现const count = ref(0)const stored = localStorage.getItem('count')if (stored) count.value = JSON.parse(stored)watch(count, (val) => { localStorage.setItem('count', JSON.stringify(val))})
// ✅ 正确:使用 VueUseimport { useLocalStorage } from '@vueuse/core'const count = useLocalStorage('count', 0)场景 2:窗口尺寸
// ❌ 错误:手动实现const width = ref(window.innerWidth)const handleResize = () => { width.value = window.innerWidth}onMounted(() => window.addEventListener('resize', handleResize))onUnmounted(() => window.removeEventListener('resize', handleResize))
// ✅ 正确:使用 VueUseimport { useWindowSize } from '@vueuse/core'const { width } = useWindowSize()场景 3:防抖
// ❌ 错误:手动实现let timer: NodeJS.Timeoutconst handleInput = (e: Event) => { clearTimeout(timer) timer = setTimeout(() => { // 处理逻辑 }, 300)}
// ✅ 正确:使用 VueUseimport { useDebounceFn } from '@vueuse/core'const handleInput = useDebounceFn((e: Event) => { // 处理逻辑}, 300)VueUse 提供了 200+ 组合式函数,覆盖了大部分常见场景。
3.3 类型安全的最佳实践
原则:Props 和 Emits 必须有完整的 TypeScript 类型
<script setup lang="ts">// ✅ 正确:完整的类型定义interface Props { title: string count?: number items: Array<{ id: number; name: string }>}
const props = withDefaults(defineProps<Props>(), { count: 0})
interface Emits { (e: 'update', value: number): void (e: 'delete', id: number): void}
const emit = defineEmits<Emits>()
// 使用emit('update', props.count + 1) // 类型安全emit('delete', 123) // 类型安全</script>复杂类型抽离到单独文件:
export interface User { id: number name: string email: string}
// UserList.vue<script setup lang="ts">import type { User } from './types/user'
interface Props { users: User[]}
const props = defineProps<Props>()</script>第四部分:实战案例
4.1 案例 1:使用 VueUse Skills 优化表单
需求:
写一个用户注册表单,要符合 Vue 3 最佳实践。
使用 Skills:
> 用 vue-skills 和 vueuse-skills 帮我写一个注册表单生成的代码:
<script setup lang="ts">import { ref, computed } from 'vue'import { useLocalStorage, useDebounceFn } from '@vueuse/core'
interface FormData { username: string email: string password: string}
// 使用 VueUse 的 useLocalStorage 自动持久化const formData = useLocalStorage<FormData>('register-form', { username: '', email: '', password: ''})
// 邮箱验证const isEmailValid = computed(() => { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ return emailRegex.test(formData.value.email)})
// 密码强度const passwordStrength = computed(() => { const password = formData.value.password if (password.length < 6) return 'weak' if (password.length < 10) return 'medium' return 'strong'})
// 防抖的用户名检查const checkUsername = useDebounceFn(async (username: string) => { const response = await fetch(`/api/check-username?name=${username}`) const { available } = await response.json() return available}, 300)
// 提交表单const handleSubmit = async () => { if (!isEmailValid.value) { alert('邮箱格式不正确') return }
const response = await fetch('/api/register', { method: 'POST', body: JSON.stringify(formData.value) })
if (response.ok) { // 注册成功,清除缓存 formData.value = { username: '', email: '', password: '' } }}</script>
<template> <form @submit.prevent="handleSubmit"> <input v-model="formData.username" placeholder="用户名" /> <input v-model="formData.email" placeholder="邮箱" /> <span v-if="!isEmailValid && formData.email">邮箱格式不正确</span>
<input v-model="formData.password" type="password" placeholder="密码" /> <span>密码强度:{{ passwordStrength }}</span>
<button type="submit">注册</button> </form></template>Skills 的价值:
- 自动使用
useLocalStorage持久化表单数据 - 自动使用
useDebounceFn防抖 - 使用
computed做验证 - 类型安全的表单数据
4.2 案例 2:使用 react-skills 优化性能
需求:
优化一个 React 仪表盘组件的性能。
使用 Skills:
> 用 react-skills 帮我优化这个组件的性能优化前:
'use client'import { useEffect, useState } from 'react'
export default function Dashboard() { const [user, setUser] = useState(null) const [posts, setPosts] = useState([]) const [comments, setComments] = useState([])
useEffect(() => { // 请求瀑布:串行获取数据 fetch('/api/user').then(res => res.json()).then(data => { setUser(data) fetch(`/api/posts?userId=${data.id}`) .then(res => res.json()) .then(posts => { setPosts(posts) fetch(`/api/comments?postId=${posts[0].id}`) .then(res => res.json()) .then(setComments) }) }) }, [])
return <div>...</div>}优化后:
// Server Component(无需 'use client')export default async function Dashboard() { // 并行获取数据,消除请求瀑布 const [user, posts, comments] = await Promise.all([ fetch('/api/user').then(res => res.json()), fetch('/api/posts').then(res => res.json()), fetch('/api/comments').then(res => res.json()) ])
return <div>...</div>}优化效果:
| 指标 | 优化前 | 优化后 | 提升 |
|---|---|---|---|
| 加载时间 | 3.5s | 1.2s | ⬆️ 2.9x |
| 请求数 | 3 次串行 | 3 次并行 | - |
Skills 的价值:
- 自动识别请求瀑布
- 建议使用 Server Components
- 使用 Promise.all 并行请求
4.3 案例 3:创建团队代码审查 Skill
需求:
团队有自己的代码审查规范,希望 AI 能自动审查。
规范要点:
- 必须使用 TypeScript
- 必须有单元测试
- 函数复杂度不超过 10
创建 Skill:
---name: team-code-reviewdescription: | 团队代码审查。自动检查代码是否符合团队规范。---
# 团队代码审查
## 审查流程
### 1. TypeScript 检查- 所有文件必须是 .ts 或 .tsx- 禁止使用 any 类型- 禁止使用类型断言(as)
### 2. 单元测试检查- 每个源文件必须有对应的测试文件- 测试文件命名:.test.ts 或 .spec.ts- 测试覆盖率 ≥ 80%
### 3. 函数复杂度检查- 使用 ESLint 的 complexity 规则- 阈值:10- 超过阈值的函数必须拆分
## 审查报告格式
\`\`\`markdown# 代码审查报告
## ✅ TypeScript 使用- 所有文件都使用 TypeScript
## ❌ 单元测试- 缺少测试文件:src/utils/helper.ts
## ✅ 函数复杂度- 所有函数复杂度 ≤ 10\`\`\`使用:
> 帮我审查这个项目的代码AI 会自动按照 Skill 里的流程审查代码,并生成报告。
4.4 案例 4:创建业务逻辑开发 Skill
需求:
写一个电商系统的订单处理逻辑,要符合团队规范。
创建 Skill:
---name: ecommerce-orderdescription: | 电商订单处理逻辑。当需要写订单相关的业务逻辑时使用。---
# 电商订单处理
## 订单状态流转
\`\`\`待支付 → 已支付 → 待发货 → 已发货 → 已完成 ↓ 已取消\`\`\`
## 核心规则
### 1. 订单创建- 必须验证库存- 必须锁定库存- 必须生成唯一订单号
### 2. 订单支付- 必须验证订单状态(待支付)- 必须调用支付网关- 必须记录支付日志
### 3. 订单发货- 必须验证订单状态(已支付)- 必须生成物流单号- 必须发送发货通知
## 代码模板
\`\`\`typescriptinterface Order { id: string userId: string items: OrderItem[] status: OrderStatus totalAmount: number createdAt: Date}
enum OrderStatus { PENDING = 'pending', PAID = 'paid', SHIPPED = 'shipped', COMPLETED = 'completed', CANCELLED = 'cancelled'}
class OrderService { async createOrder(userId: string, items: OrderItem[]): Promise<Order> { // 1. 验证库存 await this.checkInventory(items)
// 2. 锁定库存 await this.lockInventory(items)
// 3. 生成订单 const order = await this.generateOrder(userId, items)
return order }
async payOrder(orderId: string): Promise<void> { // 1. 验证订单状态 const order = await this.getOrder(orderId) if (order.status !== OrderStatus.PENDING) { throw new Error('订单状态不正确') }
// 2. 调用支付网关 await this.callPaymentGateway(order)
// 3. 更新订单状态 await this.updateOrderStatus(orderId, OrderStatus.PAID)
// 4. 记录日志 await this.logPayment(orderId) }}\`\`\`使用:
> 用 ecommerce-order skill 帮我写订单处理逻辑AI 会自动按照 Skill 里的规范生成代码。
第五部分:最佳实践
5.1 优质 Skills 检查清单
元数据:
- name 简洁明确
- description 包含触发条件
- description 包含适用场景
文档结构:
- SKILL.md < 500 行
- 有清晰的章节结构
- 有具体的代码示例(❌/✅ 对比)
- 有错误处理说明
代码质量:
- 脚本放在 scripts/ 目录
- 脚本有清晰的命名
- 脚本有错误处理
5.2 5 个实用开发技巧
技巧 1:description 要清晰触发条件
---description: | 当用户说"写 Vue 组件"、"审查 Vue 代码"时使用。---技巧 2:用示例而非抽象描述
❌ 错误:避免解构 reactive 对象✅ 正确:\`\`\`typescriptconst state = reactive({ count: 0 })const { count } = toRefs(state)\`\`\`技巧 3:控制 SKILL.md 在 500 行以内
超过 500 行,拆分为子文档。
技巧 4:写清楚判断条件和错误处理
## 执行前检查- [ ] 确认项目使用 Vue 3- [ ] 确认已安装 VueUse
## 错误处理### 错误 1:未安装 VueUse提示:检测到项目未安装 VueUse,是否需要安装?技巧 5:测试边缘情况
## 边缘情况### 情况 1:用户上传的文件格式不支持处理:自动转换为支持的格式5.3 常见问题与解决方案
问题 1:Skill 不被触发
原因: description 不够清晰
解决:
---description: | 触发条件: - 用户说"写 Vue 组件" - 用户说"审查 Vue 代码"---问题 2:Token 消耗过大
原因: SKILL.md 太长
解决: 拆分子文档,把详细内容放 references/
问题 3:多个 Skills 冲突
原因: 触发条件重叠
解决: 在 description 中明确区分场景
总结:从 0 到 1 创建你的第一个 Skill
核心要点
-
使用 Skills
- Claude Code:功能完整
- VS Code + Cline:开源免费
-
编写 Skills
- SKILL.md < 500 行
- 用示例而非说教
- 写清楚触发条件
-
vue-skills 的设计
- 按主题拆分子文档
- 5 个响应式陷阱
- VueUse 最佳实践
-
实战案例
- VueUse 优化表单
- react-skills 优化性能
- 团队代码审查
- 业务逻辑开发
推荐学习路径
第一步:体验(1-2 天)
- 安装 Claude Code 或 Cline
- 克隆 vue-skills
- 试用 3-5 次
第二步:创建(1-2 天)
- 选择一个重复性工作
- 梳理流程
- 创建第一个 Skill
第三步:优化(1 周)
- 研读 vue-skills 的设计
- 总结最佳实践
- 优化自己的 Skill
参考资料
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!