# vue开发

## 规则（Rules）

# Vue开发规范

## 适用对象和范围

本规范适用于所有使用Vue框架进行前端应用开发的场景，包括组件编写、路由配置、状态管理和API对接。

---

## 1. 组件命名规范

**规则**：组件文件名必须使用小写蛇形（snake_case），与组件注册名一致。

| 组件文件 | 组件注册名 | 模板引用 |
|---------|-----------|---------|
| `user_card.vue` | `name: 'user_card'` | `<user_card>` |
| `nav_bar.vue` | `name: 'nav_bar'` | `<nav_bar>` |

- ✅ 正确：`user_card.vue` → `name: 'user_card'` → `<user_card></user_card>`
- ❌ 错误：`UserCard.vue` → `name: 'UserCard'` → `<UserCard></UserCard>`

**违反后果**：大驼峰命名在Vue中可能导致模板解析问题，特别是在原生HTML中。

---

## 2. 变量/函数命名规范

**规则**：变量使用小写蛇形（snake_case），函数使用小驼峰（camelCase）。

- ✅ 正确：`let user_name = '张三';`、`function getUserData() {}`
- ❌ 错误：`let userName = '张三';`（Vue项目中变量用snake_case）、`function get_user_data() {}`

**违反后果**：命名不一致导致代码可读性差，与其他JS代码风格冲突。

---

## 3. 缩进规范

**规则**：统一使用2个空格缩进。

- ✅ 正确：模板、脚本、样式均使用2空格
- ❌ 错误：使用Tab或4空格

**违反后果**：缩进不一致导致代码结构混乱。

---

## 4. 目录结构规范

**规则**：Vue项目必须遵循以下目录结构。

```
./project/{项目名}/vue/
├── src/
│   ├── app.vue
│   ├── main.js
│   ├── components/       ← 公共组件
│   ├── views/            ← 页面组件
│   ├── router/
│   │   └── index.js
│   ├── store/
│   │   └── index.js
│   ├── api/
│   │   └── index.js
│   └── assets/
│       ├── css/
│       ├── img/
│       └── font/
├── index.html
├── package.json
└── vite.config.js
```

**违反后果**：目录混乱导致组件和文件难以查找，构建配置复杂。

---

## 5. 组件结构规范

**规则**：每个 `.vue` 单文件组件必须包含 `<template>`、`<script>`、`<style>` 三部分，按此顺序排列。

- ✅ 正确：
```vue
<template>
  <div class="container">...</div>
</template>

<script>
export default {
  name: 'user_card'
}
</script>

<style scoped>
.container { ... }
</style>
```

**违反后果**：组件结构不完整或顺序混乱导致Vue编译器报错或样式污染。

---

## 6. 数据驱动规范

**规则**：禁止直接操作DOM，必须使用Vue的数据驱动方式（`v-model`、`v-bind`、`v-for`、`v-if`等）。

- ✅ 正确：`<input v-model="userName">`、`:class="{ active: isActive }"`
- ❌ 错误：`document.querySelector('#input').value = 'xxx'`

**违反后果**：直接操作DOM违背Vue的设计理念，导致数据和视图不同步。

---

## 7. API调用规范

**规则**：所有后端数据操作必须通过API接口调用，禁止在前端直接操作数据库。

- ✅ 正确：`axios.get('/api/users').then(res => this.users = res.data)`
- ❌ 错误：前端代码中直接拼接SQL或操作数据库

**违反后果**：直接操作数据库暴露数据库结构，存在严重安全风险。

---

## 8. 组件拆分规范

**规则**：禁止将全部业务逻辑写在一个组件中，必须按功能拆分为多个组件。

- ✅ 正确：`UserList.vue`、`UserCard.vue`、`UserForm.vue` 分别管理不同功能
- ❌ 错误：一个 `UserManage.vue` 包含所有功能

**违反后果**：组件过大导致难以维护、测试和复用。

## 方法（Methods）

# Vue开发方法

## 前置条件

- [ ] 已获取需求文档和API设计文档
- [ ] 已确定页面结构和组件划分
- [ ] 已了解后端API接口地址和参数

## 流程概览

分析需求 → 初始化项目结构 → 配置构建工具 → 编写Vue组件 → 配置路由 → 配置状态管理 → 封装API接口 → 验证完整性

## 详细步骤

### 步骤1：分析需求
分析需求文档和API设计文档，确定页面结构、组件划分和数据接口。

### 步骤2：初始化Vue项目结构
创建Vue项目目录结构。

## 技巧（Tips）

# Vue开发技巧

## 1. 使用计算属性替代方法

**适用场景**：需要基于响应式数据派生新数据时。

**具体做法**：使用 `computed` 计算属性替代 `methods` 中的函数。

**对比说明**：

| 维度 | methods方法 | computed计算属性 |
|------|------------|----------------|
| 缓存 | 每次调用都执行 | 依赖不变时不重新计算 |
| 响应式 | 需要手动触发 | 自动追踪依赖 |
| 模板调用 | `{{ formatName() }}` | `{{ formattedName }}` |

**示例**：
```javascript
// ❌ 不推荐
methods: {
  formatName() {
    return this.firstName + ' ' + this.lastName;
  }
}

// ✅ 推荐
computed: {
  formattedName() {
    return this.firstName + ' ' + this.lastName;
  }
}
```

**注意事项**：计算属性默认只有getter，如果需要设置值，需要提供setter。

---

## 2. 使用watch监听异步变化

**适用场景**：需要监听数据变化并执行异步操作时。

**具体做法**：使用 `watch` 监听器替代 `computed` 处理异步场景。

**对比说明**：

| 维度 | computed | watch |
|------|---------|-------|
| 同步/异步 | 只能同步 | 支持异步 |
| 返回值 | 必须有返回值 | 不要求返回值 |
| 副作用 | 不应有副作用 | 适合处理副作用 |

**示例**：
```javascript
// ✅ 使用watch监听搜索关键词变化
watch: {
  searchQuery: {
    handler(newVal) {
      this.debouncedSearch(newVal);
    },
    debounce: 300
  }
}
```

**注意事项**：`watch` 默认只监听浅层变化，深层对象需要设置 `deep: true`。

---

## 3. 使用scoped样式防止样式污染

**适用场景**：编写组件样式时。

**具体做法**：在 `<style>` 标签上添加 `scoped` 属性。

**对比说明**：

| 维度 | 无scoped | 有scoped |
|------|---------|---------|
| 作用域 | 全局 | 当前组件 |
| 样式冲突 | 容易冲突 | 自动隔离 |
| 覆盖子组件 | 直接覆盖 | 需使用深度选择器 `::v-deep` |

**示例**：
```vue
<template>
  <div class="card">
    <slot></slot>
  </div>
</template>

<style scoped>
.card {
  border: 1px solid #e8e8e8;
  padding: 1rem;
}
</style>
```

**注意事项**：`scoped` 样式不能影响子组件的根元素，如果需要覆盖子组件样式，使用 `::v-deep`。

---

## 4. 常见问题速查

| 问题 | 原因 | 解决方案 |
|------|------|---------|
| 组件未显示 | 未注册或未导入 | 检查 `components` 注册和导入路径 |
| 数据修改但视图未更新 | 直接修改了数组/对象 | 使用 `Vue.set` 或展开运算符创建新对象 |
| 路由跳转后页面空白 | 路由配置错误或组件路径错误 | 检查路由 `path` 和 `component` 导入路径 |
| `this` 指向错误 | 回调函数中丢失上下文 | 使用箭头函数或在 `created` 中 `bind` |
| API请求跨域 | 前后端域名不一致 | 配置代理（vite.config.js中的proxy）或后端配置CORS |
