plugins/vue-coder/skills/vue2-best-practices/SKILL.md
Vue 2 维护与开发最佳实践指南 - Options API、Vuex 及向 Vue 3 迁移准备。 当用户说"Vue 2组件"、"Options API"、"Vuex"、"Vue 2项目"、"Vue 2迁移"、"Vue mixin"、"Vue 2最佳实践"时使用此技能。 涵盖:Options API 规范(选项顺序、props 验证)、Vuex 模块化(namespaced modules)、逻辑复用(避免 mixin,使用工具函数)、迁移准备(停止使用 Filters、引入 Composition API 插件)。 提供 Vue 2 代码示例、反模式警告和迁移建议。
npx skillsauth add protagonistss/ithinku-plugins vue2-best-practicesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
本技能旨在指导开发者维护现有的 Vue 2 项目,编写清晰、可预测的 Options API 代码,并为未来迁移到 Vue 3 做准备。 核心原则:规范化 Options API、谨慎使用 Mixins、组件解耦。
namecomponentspropsdatacomputedwatchlifecycle hooks (created, mounted, etc.)methodsdata 必须始终是一个返回对象的函数,防止组件实例间状态污染。new Vue()) 进行通信,这会导致事件流难以追踪。namespaced: true) 来组织 Store。mapState, mapGetters, mapActions 简化组件内的调用。methods 或生命周期钩子中使用箭头函数,这会导致 this 指向错误。ref。computed 属性来处理派生数据,而不是滥用 watch。Vue.prototype 上挂载过多全局变量。$listeners)。<script setup>),以便逐步过渡到 Vue 3 的写法。<template>
<div class="user-card">
<h3>{{ formattedName }}</h3>
<p>{{ user.email }}</p>
<button @click="handleEdit">编辑</button>
</div>
</template>
<script>
// ✅ 遵循选项顺序规范
export default {
name: 'UserCard', // 1. name
components: { // 2. components
EditButton
},
props: { // 3. props - 带类型验证
user: {
type: Object,
required: true,
validator: (value) => ['id', 'name', 'email'].every(key => key in value)
}
},
data() { // 4. data - 必须是函数
return {
isEditing: false
}
},
computed: { // 5. computed
formattedName() {
return this.user.name.toUpperCase()
}
},
watch: { // 6. watch
'user.id': {
handler(newId) {
this.fetchUserData(newId)
},
immediate: true
}
},
created() { // 7. 生命周期钩子
this.initializeComponent()
},
mounted() {
this.setupEventListeners()
},
methods: { // 8. methods - 避免箭头函数
handleEdit() {
this.$emit('edit', this.user.id)
},
fetchUserData(id) {
// 数据获取逻辑
},
initializeComponent() {
// 初始化逻辑
},
setupEventListeners() {
// 事件监听
}
}
}
</script>
// store/modules/user.js
// ✅ 使用命名空间模块
export default {
namespaced: true,
state: () => ({
user: null,
token: null,
loading: false
}),
getters: {
isLoggedIn: state => !!state.token,
displayName: state => state.user?.name ?? '访客'
},
// Mutations 必须是同步的
mutations: {
SET_USER(state, user) {
state.user = user
},
SET_TOKEN(state, token) {
state.token = token
},
SET_LOADING(state, loading) {
state.loading = loading
}
},
// Actions 处理异步逻辑
actions: {
async login({ commit }, credentials) {
commit('SET_LOADING', true)
try {
const { user, token } = await authService.login(credentials)
commit('SET_USER', user)
commit('SET_TOKEN', token)
return { success: true }
} catch (error) {
return { success: false, error: error.message }
} finally {
commit('SET_LOADING', false)
}
},
logout({ commit }) {
commit('SET_USER', null)
commit('SET_TOKEN', null)
}
}
}
<!-- 组件中使用 Vuex -->
<template>
<div v-if="isLoggedIn">
<p>欢迎, {{ displayName }}</p>
<button @click="logout">退出</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex'
export default {
name: 'UserStatus',
computed: {
// ✅ 使用 map 辅助函数
...mapState('user', ['loading']),
...mapGetters('user', ['isLoggedIn', 'displayName'])
},
methods: {
...mapActions('user', ['logout'])
}
}
</script>
// ❌ 避免 Mixin
const userMixin = {
data() {
return { user: null }
},
methods: {
fetchUser() { /* ... */ }
}
}
// ✅ 使用工具函数
// utils/user.js
export function createUserService() {
return {
user: null,
async fetchUser(id) {
this.user = await api.getUser(id)
return this.user
}
}
}
// 组件中使用
import { createUserService } from '@/utils/user'
export default {
data() {
return {
userService: createUserService()
}
},
async created() {
await this.userService.fetchUser(this.userId)
}
}
<script>
export default {
props: {
// ✅ 基础类型验证
title: String,
// ✅ 多种可能的类型
value: [String, Number],
// ✅ 必填字段
userId: {
type: [String, Number],
required: true
},
// ✅ 带默认值
size: {
type: String,
default: 'medium',
validator: (value) => ['small', 'medium', 'large'].includes(value)
},
// ✅ 对象/数组默认值使用工厂函数
config: {
type: Object,
default: () => ({
theme: 'light',
locale: 'zh-CN'
})
},
// ✅ 自定义验证
email: {
type: String,
validator: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
}
}
}
</script>
<template>
<div>
<p>计数: {{ count }}</p>
<button @click="increment">+1</button>
</div>
</template>
<script>
// Vue 2.7+ 可以使用 Composition API
import { ref, computed, onMounted } from 'vue'
export default {
name: 'Counter',
// ✅ 渐进式迁移:setup 函数
setup() {
const count = ref(0)
const doubled = computed(() => count.value * 2)
function increment() {
count.value++
}
onMounted(() => {
console.log('Counter mounted')
})
return {
count,
doubled,
increment
}
}
}
</script>
# 规范化 Options 顺序
/vue-coder 重新排列这个组件的选项顺序,使其符合最佳实践。
# 移除 Mixin
/vue-coder 分析这个组件使用的 Mixin,尝试将其重构为普通的函数导入或 HOC。
# Vuex 模块化
/vue-coder 将这个庞大的 Vuex store 拆分为独立的命名空间模块。
development
Vue 3 开发最佳实践指南 - Composition API、Script Setup、Pinia、TypeScript 集成及性能优化。 当用户说"Vue 3组件"、"Composition API"、"script setup"、"Pinia"、"Vue 3项目"、"ref reactive"、"defineProps defineEmits"、"Composable"、"Vue 3优化"时使用此技能。 涵盖:Script Setup 与 Composition API、响应式数据选择(ref vs reactive)、组件通信(Props/Emits/v-model/Slots)、Composables 设计模式、Pinia Setup Store、性能优化(v-memo、shallowRef、KeepAlive)。 提供 TypeScript 代码示例、反模式对照表、迁移指南和示例文件引用。
development
核心设计能力 - 提供配色、布局、组件样式生成及反模式检查。 当用户说"设计UI"、"生成样式"、"页面布局"、"CSS样式"、"组件设计"、"配色方案"、"设计系统"、"前端样式"、"响应式设计"、"动画效果"时使用此技能。 支持多种设计风格:Neo-Brutalism、Glassmorphism、Editorial、Cyberpunk。 提供配色方案、布局生成、组件样式、微交互动效、响应式网格。拒绝"AI廉价感",追求大胆、独特、细节丰富的设计。 重要特性:提供反模式检查,避免泛滥的渐变、无聊的阴影、默认圆角等平庸设计。
content-media
无障碍设计审查与修复能力。 当用户说"无障碍"、"a11y"、"WCAG"、"键盘导航"、"屏幕阅读器"、"颜色对比度"、"ARIA"、"可访问性"、"辅助功能"、"盲人友好"时使用此技能。 基于 WCAG 2.1 标准,检测图片 Alt 文本缺失、表单 Label 关联、键盘可访问性、颜色对比度不足、ARIA 属性误用等问题。 提供修复代码示例:语义化标签、焦点管理、焦点陷阱、屏幕阅读器支持。输出合规性检查报告和修复建议。
development
分析源代码并生成对应的单元测试用例。 当用户说"生成测试"、"写单元测试"、"添加测试用例"、"测试覆盖"、"单元测试"、"vitest测试"、"jest测试"、"pytest测试"、"测试代码"时使用此技能。 支持多种语言和框架:JavaScript/TypeScript (Jest, Vitest, Mocha)、Python (pytest, unittest)、Java (JUnit 5, TestNG)。 自动生成:正常流程测试、边界条件测试、异常情况测试、Mock 配置。输出遵循 AAA 模式的高质量测试代码。