xml
name: vue2-elementui
description: Vue 2 + JavaScript + Element UI 编码规范,适用于 Vue 2 Options API 项目
# Vue 2 + JavaScript + Element UI 编码规范
本 skill 为 Vue 2 + Options API + Element UI 项目提供编码规范指引。
## 触发场景
当用户在 Vue 2 项目中编写或审查 `.vue` / `.js` / `.scss` / `.css` 文件时,自动应用本规范。
* * *
## 基础规范
- 路径别名、目录结构遵循**项目既有配置**(如 `jsconfig.json`、`vue.config.js`);避免 `../../../../` 式相对路径穿越。
- `.vue` 文件与模板中的组件使用 **PascalCase**(`UserCard.vue` / `<UserCard />`)。
- 样式 class 推荐 **kebab-case**;组件内自定义 class 推荐 BEM。
- 单文件建议不超过 400 行,超出应拆分组件或 mixin。
- 注释语言、标识符语言遵循项目约定;代码标识符使用英文,含义清晰。
## 命名规范
- **组件名**: PascalCase。
- **变量 / 函数**: camelCase;事件处理函数推荐 `handle` 前缀(如 `handleSubmit`)。
- **常量**: 需要时使用 UPPER_SNAKE_CASE。
- **Props / Events**: props 用 camelCase;模板事件名用 kebab-case。
- **Mixins**: 推荐 `mixin` 后缀或按功能命名(如 `tableMixin`、`formMixin`)。
- **Filters**: 推荐按功能命名(如 `formatDate`、`formatMoney`)。
- **全局组件前缀**(如有): 遵循项目统一前缀,不要自创多套命名。
## JavaScript 规范
- 使用 ES6+ 语法(`const`/`let`、箭头函数、解构、模板字符串等),但避免使用 Vue 3 / Composition API 特性。
- 避免使用 `var`;优先使用 `const`,需要重新赋值时使用 `let`。
- 对象结构优先使用 JSDoc 类型注释;复杂对象可定义 `@typedef`。
- 避免隐式类型转换,使用 `===` / `!==`。
- 公共类型与数据结构集中管理;领域类型靠近业务模块,按项目目录约定放置。
## Vue 组件规范
### 基础要求
- 新组件使用 **Options API**(`data`、`computed`、`methods`、`watch`、`mounted` 等)。
- 禁止使用 Vue 3 的 Composition API(`<script setup>`、`ref`、`reactive`、`computed`、`watchEffect` 等)。
- 需要组件名时使用 `name` 选项(调试、keep-alive、路由缓存等)。
- 路由级页面组件的 `name` 建议与路由配置保持一致。
### 组件块顺序
- `<template>` → `<script>` → `<style>`
### Script 内推荐顺序
0. 组件名 `name`
0. 第三方库 / UI 组件 import
0. 项目内模块(mixins、utils、components 等)
0. `components` 局部组件注册
0. `mixins` 混入
0. `props` 定义
0. `data()` 返回响应式数据
0. `computed` 计算属性
0. `watch` 侦听器
0. 生命周期钩子(`created`、`mounted`、`beforeDestroy` 等)
0. `methods` 方法
0. `filters` 过滤器(如需要)
### 模板约定
- 模板保持单根节点(Vue 2 限制)。
- 事件名、插槽名使用 **kebab-case**。
- 受控表单优先 `v-model`;修饰符按 Vue 2 语法书写。
- 布尔 prop 使用显式写法(如 `:visible="visible"`)。
### Props 定义
- 使用对象形式定义 props,指定 `type`、`default`、`required` 等。
- 对象/数组类型的 default 必须使用工厂函数返回。
// ✅
props: {
title: {
type: String,
default: ''
},
list: {
type: Array,
default: () => []
}
}
// ❌
props: {
list: {
type: Array,
default: []
}
}
### $emit 事件
- 事件名使用 **kebab-case**(如 `this.$emit('update-data', payload)`)。
- 模板中监听时使用 kebab-case(如 `@update-data="handleUpdate"`)。
### 生命周期
- Vue 2 使用 `beforeDestroy` 而非 Vue 3 的 `onUnmounted`。
- 在 `beforeDestroy` 中清理定时器、事件监听、订阅等副作用。
### Element UI 组件使用
- 优先使用 Element UI 提供的组件,避免重复造轮子。
- 表单校验使用 `el-form` + `rules` 配置。
- 表格使用 `el-table` + `el-table-column`,自定义列内容使用作用域插槽。
- 对话框使用 `el-dialog`,注意 `visible` 双向绑定与 `before-close` 钩子。
- 消息提示使用 `this.$message`、`this.$confirm`、`this.$notify` 等全局方法。
## CSS 规范
### SFC 样式块
- 样式块位于 `<script>` 之后:`<style lang="scss|less|css" scoped>`。
- 默认使用 **`scoped`**,避免污染全局;需要全局样式时须在注释中说明原因。
- 预处理器(SCSS/LESS)与纯 CSS 按项目既有约定选用,同一组件内保持一致。
### 命名约定
- 自定义 class 使用 **kebab-case**。
- 组件内自定义 class 推荐 **BEM**(Block Element Modifier)。
- Element UI 自带类名、项目全局工具类不在 BEM 约束范围内;仅约束本组件新增的 class。
- 深度选择器使用 `::v-deep`(Vue 2 写法),不要使用 Vue 3 的 `:deep()` 语法。
### BEM 结构
| 类型 | 格式 | 示例 |
| ------------- | ---------------------------------------------- | ------------------------------------------------- |
| Block(块) | `block` | `user-card`、`search-form` |
| Element(元素) | `block__element` | `user-card__avatar`、`search-form__input` |
| Modifier(修饰符) | `block--modifier` 或 `block__element--modifier` | `user-card--compact`、`search-form__btn--disabled` |
约定:
- **Block** 对应当前组件语义,一个 SFC 通常只设一个 Block。
- **Element** 用双下划线 `__` 连接 Block;多级语义用 `-` 连接,**禁止** `block__a__b` 链式元素写法。
- **Modifier** 用双连字符 `--` 表示状态或变体(如 `--active`、`--disabled`、`--compact`)。
- 在 `<style scoped>` 中优先用预处理器嵌套表达 BEM(`&__element`、`&--modifier`)。
### Element UI 样式覆盖
- 需要覆盖 Element UI 组件内部样式时,使用 `::v-deep` 深度选择器。
- 避免使用 `!important`,优先通过提高选择器优先级实现覆盖。
## 导入与排序
推荐分组(同组内按字母序):
0. 第三方库(Vue、Element UI、Axios 等)
0. 项目内部(mixins、filters、utils、components、styles、assets)
- 不要重复 import 已全局注册的 Element UI 组件。
- 静态资源、样式按项目约定引入,避免大段内联样式。
## 目录与组织
- 遵循项目现有目录划分(如 `components`、`views`、`mixins`、`filters`、`utils`、`api` 等)。
- 可复用 UI 放组件目录;页面级逻辑放 views 或路由对应模块。
- 跨页面逻辑抽到 mixins 或 utils;纯函数抽到 utils。
- 常量、枚举集中管理,避免魔法字符串散落。
## 代码质量与 Lint
- 遵循项目 **ESLint**、**Stylelint** 配置,不擅自关闭规则。
- 必要的 `eslint-disable` 须注释说明原因。
- Vue 相关 lint(block 顺序、事件命名等)以项目 ESLint 配置为准。
## 最佳实践
- **组件封装**: 优先复用 Element UI 组件与项目已有封装;透传 props / attrs 时保持 API 一致。
- **响应式**: 数据定义在 `data()` 中返回对象;派生数据用 `computed`;副作用用 `watch`。
- **性能**: 模板避免复杂计算;大列表考虑分页或虚拟滚动;路由与组件按需加载。
- **代码复用**: 重复逻辑下沉 mixin 或 utils,不要复制粘贴。
## 禁止
- 禁止 AI 主动添加项目没用过的依赖。
- 禁止在 Vue 2 项目中使用 Vue 3 的 Composition API(`<script setup>`、`ref`、`reactive`、`computed` 等)。
- 禁止在 Vue 2 项目中使用 TypeScript 语法(除非项目明确配置了 TS)。