---
description: 代码质量标准 - 复杂度控制、安全性、性能优化、错误处理。涉及代码审查、优化、重构时触发。
---

# 代码质量规范

该规则定义代码质量标准，包括复杂度控制、安全防护、性能优化、错误处理。

---

## 必须遵守

- ✅ 单个函数圈复杂度不得超过 10
- ✅ 单个文件代码行数不得超过 300 行
- ✅ 函数参数数量不得超过 5 个
- ✅ 超过复杂度限制的函数必须拆分
- ✅ 用户输入必须转义处理（`v-text` 而非 `v-html`）
- ✅ 动态 HTML 必须通过 DOMPurify 清洗
- ✅ URL 参数必须验证和清洗
- ✅ 所有异步操作必须有错误处理
- ✅ HTTP 错误必须在拦截器中统一处理
- ✅ 关键错误必须上报到监控平台
- ✅ 必须处理加载、空数据、超时等边界状态
- ✅ 频繁切换的元素使用 `v-show` 而非 `v-if`
- ✅ 长列表必须使用虚拟滚动
- ✅ 图片和路由必须懒加载
- ✅ 大型库必须按需导入
- ✅ 必须使用最新稳定版本 API，禁止废弃 API
- ✅ 仅生成必要代码文件，禁止冗余文档

---

## 严格禁止

- ❌ 单个函数超过 50 行代码
- ❌ 深层嵌套超过 3 层
- ❌ 使用 `any` 类型（除非必要）
- ❌ 注释掉的代码长期存在
- ❌ 生成多余文档文件（README、CHANGELOG、TODO）
- ❌ 使用 `@deprecated` 废弃 API
- ❌ 使用实验性 API（`experimental_*`、`unstable_*`）
- ❌ 前端存储敏感信息（密码、完整 Token）
- ❌ 使用 `v-html` 渲染用户输入
- ❌ 代码中硬编码密钥或密码
- ❌ 空的 catch 块
- ❌ 错误提示中暴露技术细节
- ❌ 循环中频繁修改响应式状态
- ❌ 模板中使用复杂计算（应使用 computed）
- ❌ 全量导入大型库（lodash、echarts）

---

## 最佳实践

- 💡 提前返回减少嵌套层级
- 💡 提取复杂逻辑为独立函数
- 💡 代码即文档，通过清晰命名自解释
- 💡 大对象使用 `shallowRef`
- 💡 不需要响应式的数据使用普通对象
- 💡 分包策略利用浏览器缓存

---

## 代码示例

### 提前返回

```typescript
// ✅
function processData(data: Data) {
  if (!data) return null;
  if (!data.isValid) return null;
  return transform(data);
}

// ❌
function processData(data: Data) {
  if (data) {
    if (data.isValid) {
      return transform(data);
    }
  }
  return null;
}
```

### 提取复杂逻辑

```typescript
// ✅
function validateUser(user: User) {
  return hasValidEmail(user) && hasValidAge(user) && hasValidRole(user);
}

// ❌
function validateUser(user: User) {
  return (
    user.email &&
    /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(user.email) &&
    user.age >= 18 &&
    user.age <= 100 &&
    ["admin", "user", "guest"].includes(user.role)
  );
}
```

### XSS 防护

```vue
<!-- ✅ -->
<template>
  <div>{{ userInput }}</div>
  <div v-text="userInput"></div>
</template>

<!-- ❌ -->
<template>
  <div v-html="userInput"></div>
</template>
```

### 敏感信息处理

```typescript
function maskPhone(phone: string) {
  return phone.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
}
```

### 路由懒加载

```typescript
const routes = [
  {
    path: "/dashboard",
    component: () => import("./views/Dashboard.vue"),
  },
];
```

### 虚拟滚动

```vue
<template>
  <RecycleScroller :items="items" :item-size="50">
    <template #default="{ item }">
      <div>{{ item.name }}</div>
    </template>
  </RecycleScroller>
</template>
```

### 响应式优化

```typescript
const largeData = shallowRef({
  /* 大量数据 */
});
const config = { apiUrl: "..." }; // 不需要响应式
```

### HTTP 错误统一处理

```typescript
request.interceptors.response.use(
  (response) => response.data,
  (error) => {
    const status = error.response?.status;
    const messages: Record<number, string> = {
      401: "登录已过期",
      403: "没有权限",
      404: "资源不存在",
      500: "服务器错误",
    };
    showToast(messages[status] || "请求失败");
    if (status === 401) router.push("/login");
    if (status === 500) reportError(error);
    return Promise.reject(error);
  }
);
```

### 错误捕获与上报

```typescript
// 全局错误捕获
app.config.errorHandler = (err, instance, info) => {
  reportError(err as Error, { componentName: instance?.$options.name, info });
};

window.addEventListener("unhandledrejection", (event) => {
  reportError(event.reason);
});

// 错误上报
export function reportError(error: Error, context?: Record<string, any>) {
  if (import.meta.env.DEV) {
    console.error("Error:", error, "Context:", context);
    return;
  }
  window.Sentry?.captureException(error, { extra: context });
}
```

### 边界状态处理

```vue
<template>
  <div class="data-list">
    <van-loading v-if="loading">加载中...</van-loading>
    <van-empty v-else-if="error" description="加载失败">
      <van-button @click="retry">重试</van-button>
    </van-empty>
    <van-empty v-else-if="!data?.length" description="暂无数据" />
    <div v-else v-for="item in data" :key="item.id">{{ item.name }}</div>
  </div>
</template>
```
