SKILL.md
readonly只读
name
vue-best-practices
description
必须用于 Vue.js 任务。强烈推荐使用 Composition API 配合 `<script setup>` 和 TypeScript 作为标准方法。涵盖 Vue 3、SSR、Volar、vue-tsc。在处理任何 Vue、.vue 文件、Vue Router、Pinia 或使用 Vue 的 Vite 项目时加载。除非项目明确要求 Options API,否则始终使用 Composition API。
Vue 最佳实践工作流
将此技能作为指令集使用。按顺序遵循工作流,除非用户明确要求不同的顺序。
核心原则
- 保持状态可预测: 单一数据源,其他一切由此派生。
- 使数据流显式化: 大多数情况下,Props 向下传递,Events 向上传递。
- 偏好小型、专注的组件: 更易于测试、复用和维护。
- 避免不必要的重新渲染: 明智地使用计算属性和侦听器。
- 可读性至关重要: 编写清晰、自文档化的代码。
1) 编码前确认架构(必需)
- 默认技术栈:Vue 3 + Composition API +
<script setup lang="ts">。 - 如果项目明确使用 Options API,则加载
vue-options-api-best-practices技能(如果可用)。 - 如果项目明确使用 JSX,则加载
vue-jsx-best-practices技能(如果可用)。
1.1 必读核心参考(必需)
- 在实现任何 Vue 任务之前,确保阅读并应用以下核心参考:
references/reactivity.mdreferences/sfc.mdreferences/component-data-flow.mdreferences/composables.md
- 在整个任务过程中,将这些参考保留在活跃的工作上下文中,而不仅仅在出现特定问题时。
1.2 编码前规划组件边界(必需)
在实现任何非平凡功能之前,创建一个简短的组件映射。
- 用一句话定义每个组件的单一职责。
- 默认将入口/根组件和路由级视图组件作为组合表面。
- 将功能 UI 和功能逻辑移出入口/根/视图组件,除非任务本身是一个小型单文件演示。
- 在映射中为每个子组件定义 props/emits 契约。
- 当添加多个组件时,优先使用功能文件夹布局(
components/<feature>/...,composables/use<Feature>.ts)。
2) 应用基本的 Vue 基础(必需)
这些是必须了解的基本知识。在每个 Vue 任务中,使用已在第 1.1 节加载的核心参考,应用所有这些知识。
响应式
- 必读参考来自 1.1:reactivity
- 保持源状态最小化(
ref/reactive),尽可能通过computed派生一切。 - 如果需要,使用侦听器处理副作用。
- 避免在模板中重新计算昂贵的逻辑。
SFC 结构和模板安全
- 必读参考来自 1.1:sfc
- 保持 SFC 部分的顺序为:
<script>→<template>→<style>。 - 保持 SFC 职责集中;拆分大型组件。
- 保持模板声明式;将分支/派生逻辑移至脚本。
- 应用 Vue 模板安全规则(
v-html、列表渲染、条件渲染选择)。
保持组件专注
当组件具有多个明确职责(例如数据编排 + UI,或多个独立的 UI 部分)时,进行拆分。
- 偏好更小的组件 + 组合式函数,而不是一个“巨型组件”。
- 将 UI 部分移至子组件(props 传入,events 传出)。
- 将状态/副作用移至组合式函数(
useXxx())。
应用客观的拆分触发条件。如果任何条件为真,则拆分组件:
- 它同时拥有编排/状态和多个部分的实质性展示标记。
- 它有 3 个或更多不同的 UI 部分(例如:表单、过滤器、列表、页脚/状态)。
- 模板块重复出现或可能变得可复用(项目行、卡片、列表条目)。
入口/根和路由视图规则:
- 保持入口/根和路由视图组件精简:应用外壳/布局、提供者连接和功能组合。
- 当功能包含独立部分时,不要将完整功能实现放在入口/根/视图组件中。
- 对于 CRUD/列表功能(待办事项、表格、目录、收件箱),至少拆分为:
- 功能容器组件
- 输入/表单组件
- 列表(和/或项目)组件
- 页脚/操作或过滤器/状态组件
- 仅对非常小的临时演示允许单文件实现;如果选择这样做,明确说明为什么拆分是不必要的。
组件数据流
- 必读参考来自 1.1:component-data-flow
- 使用 props 向下传递、events 向上传递作为主要模型。
- 仅对真正的双向组件契约使用
v-model。 - 仅对深层树依赖或共享上下文使用 provide/inject。
- 使用
defineProps、defineEmits和InjectionKey(根据需要)保持契约显式化和类型化。
组合式函数
- 必读参考来自 1.1:composables
- 当逻辑被复用、有状态或副作用较重时,将其提取到组合式函数中。
- 保持组合式函数 API 小巧、类型化和可预测。
- 将功能逻辑与展示组件分离。
3) 仅在需求要求时考虑可选功能
3.1 标准可选功能
默认不要添加这些。仅在需求存在时加载匹配的参考。
- 插槽:父组件需要控制子组件内容/布局 -> component-slots
- 透传属性:包装器/基础组件必须安全地转发属性/事件 -> component-fallthrough-attrs
- 内置组件
<KeepAlive>用于有状态视图缓存 -> component-keep-alive - 内置组件
<Teleport>用于覆盖层/传送门 -> component-teleport - 内置组件
<Suspense>用于异步子树回退边界 -> component-suspense - 动画相关功能:选择与所需运动行为匹配的最简单方法。
- 内置组件
<Transition>用于进入/离开效果 -> transition - 内置组件
<TransitionGroup>用于动画列表变化 -> transition-group - 基于类的动画用于非进入/离开效果 -> animation-class-based-technique
- 状态驱动动画用于用户输入驱动的动画 -> animation-state-driven-technique
- 内置组件
3.2 较少见的可选功能
仅在存在明确的产品或技术需求时使用。
- 指令:行为是 DOM 特定的,不适合组合式函数/组件 -> directives
- 异步组件:重型/很少使用的 UI 应懒加载 -> component-async
- 渲染函数:仅当模板无法表达需求时使用 -> render-functions
- 插件:当行为必须在应用范围内安装时使用 -> plugins
- 状态管理模式:应用范围的共享状态跨越功能边界 -> state-management
4) 在行为正确后运行性能优化
性能工作是在功能完成后的步骤。在核心行为实现并验证之前不要进行优化。
- 大型列表渲染瓶颈 -> perf-virtualize-large-lists
- 静态子树不必要地重新渲染 -> perf-v-once-v-memo-directives
- 热列表路径中的过度抽象 -> perf-avoid-component-abstraction-in-lists
- 昂贵更新触发过于频繁 -> updated-hook-performance
5) 完成前的最终自查
- 核心行为正常工作并符合需求。
- 所有必读参考已阅读并应用。
- 响应式模型最小化且可预测。
- SFC 结构和模板规则已遵循。
- 组件专注且重构良好,必要时进行拆分。
- 入口/根和路由视图组件保持为组合表面,除非有明确的临时演示例外。
- 组件拆分决策明确且可辩护(职责边界清晰)。
- 数据流契约显式化且类型化。
- 在复用/复杂性证明合理的情况下使用了组合式函数。
- 如果适用,将状态/副作用移至组合式函数。
- 仅在需求要求时使用可选功能。
- 性能更改仅在功能完成后应用。






