Skip to content
cccskills
FreePublished on GitHub

frontend-dev

前端开发规范,包含 Vue 3 编码规范、UI 风格约束、TypeScript 规范等

The English summary is being prepared. Showing the original description.

See how to install

Files included (4)

  • SKILL.md8.4 KB
  • references/date-time.md1.3 KB
  • references/frontend-style.md18.7 KB
  • references/miniapp-pitfalls.md3.7 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

前端开发规范

参考来源: Vue 官方风格指南、Element Plus 最佳实践


UI 风格约束

严格禁止(常见 AI 风格)

  • ❌ 蓝紫色霓虹渐变、发光描边、玻璃拟态
  • ❌ 大面积渐变、过多装饰性几何图形
  • ❌ 赛博风、暗黑科技风、AI 风格 UI
  • ❌ UI 文案中使用 emoji

后台系统(默认风格)

要素要求
主题使用组件库默认主题
配色黑白灰为主 + 1 个主色点缀
动效克制,仅保留必要交互反馈

技术栈

层级Vue(首选)React(备选)
框架Vue 3 + TypeScriptReact 18 + TypeScript
构建ViteVite
路由Vue Router 4React Router 6
状态PiniaZustand
UI 库Element PlusAnt Design

Vue 编码规范

组件基础

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import type { User } from '@/types'

// Props & Emits
const props = defineProps<{ userId: number }>()
const emit = defineEmits<{ (e: 'update', value: string): void }>()

// 响应式状态
const loading = ref(false)
const user = ref<User | null>(null)

// 计算属性
const displayName = computed(() => user.value?.name ?? '未知用户')

// 生命周期
onMounted(async () => { await fetchUser() })

// 方法
async function fetchUser() {
  loading.value = true
  try {
    user.value = await api.getUser(props.userId)
  } finally {
    loading.value = false
  }
}
</script>

<template>
  <div class="user-card">
    <h3>{{ displayName }}</h3>
  </div>
</template>

<style scoped>
.user-card { padding: 16px; }
</style>

命名约定

类型约定示例
组件文件PascalCase.vueUserCard.vue
ComposablesuseXxx.tsuseAuth.ts
StoreuseXxxStore.tsuseUserStore.ts

状态管理(Pinia)

// stores/user.ts
export const useUserStore = defineStore('user', () => {
  const user = ref<User | null>(null)
  const token = ref<string>('')

  const isLoggedIn = computed(() => !!token.value)

  async function login(username: string, password: string) {
    const res = await api.login(username, password)
    token.value = res.token
    user.value = res.user
  }

  return { user, token, isLoggedIn, login }
})

交互状态处理

必须处理的状态: loading、empty、error、disabled、submitting

<template>
  <el-skeleton v-if="loading" :rows="5" animated />
  <el-result v-else-if="error" icon="error" :title="error">
    <template #extra>
      <el-button @click="fetchData">重试</el-button>
    </template>
  </el-result>
  <el-empty v-else-if="list.length === 0" description="暂无数据" />
  <template v-else>
    <!-- 正常内容 -->
  </template>
</template>

TypeScript 规范

// types/user.ts
export interface User {
  id: number
  username: string
  role: 'admin' | 'user'
}

export interface ApiResponse<T = unknown> {
  code: number
  message: string
  data: T
}

API 调用类型安全

规则说明
✅ API 工具函数支持泛型get<T>(url): Promise<T> 而非返回 unknown
✅ 调用处指定泛型或断言get<UserInfo>(url) 或 data as typeof ref.value
❌ 禁止 as any 绕过掩盖类型问题,后续维护踩坑
// ❌ get() 返回 unknown,赋值报 TS2322
const data = await get('/contact/config')
contact.value = data

// ❌ as any 绕过
contact.value = data as any

// ✅ 泛型约束(推荐)
const data = await get<ContactConfig>('/contact/config')
contact.value = data

// ✅ 类型断言(最小改动)
contact.value = data as typeof contact.value

性能优化

场景方案
大列表虚拟滚动
路由懒加载 () => import()
计算使用 computed 缓存
大数据使用 shallowRef
// 路由懒加载
const routes = [
  { path: '/dashboard', component: () => import('@/views/Dashboard.vue') }
]

// 请求防抖
import { useDebounceFn } from '@vueuse/core'
const debouncedSearch = useDebounceFn((keyword) => api.search(keyword), 300)

目录结构

src/
├── assets/
│   └── styles/          # 全局/共享样式
├── api/                 # API 请求
├── components/          # 通用组件
├── composables/         # 组合式函数
├── router/              # 路由配置
├── stores/              # Pinia stores
├── types/               # TypeScript 类型
├── utils/               # 工具函数
├── views/               # 页面组件
├── App.vue
└── main.ts

样式管理规范

规则说明
❌ 禁止在 .vue 中写大段样式<style> 块不超过 20 行
❌ 禁止在 .tsx 中写大段内联样式样式对象/CSS-in-JS 不超过 20 行
✅ 共享样式抽到 src/assets/styles/按模块拆分文件
✅ 组件内只保留极简样式Vue: scoped 微调;React: className 引用
src/assets/styles/
├── variables.scss       # 变量(颜色、间距、字号)
├── common.scss          # 通用样式
└── [module].scss        # 按模块拆分

请求体完整性规范

规则说明
❌ 禁止 UI 可选字段未传入 API用户选择/输入的字段必须全部传入请求体
✅ 提交函数与表单字段一一对应用 TypeScript interface 约束请求体
// ❌ UI 有支付方式选择器,但请求体没传 payMethod
const payMethod = ref<'wechat' | 'points' | 'mixed'>('wechat')

async function createOrder() {
  await api.createOrder({
    items: orderItems.value,
    addressId: selectedAddress.value.id,
    // payMethod 忘记传了!支付方式选择 UI 形同虚设
  })
}

// ✅ 请求体与 UI 表单字段对应
interface CreateOrderRequest {
  items: OrderItem[]
  addressId: number
  payMethod: 'wechat' | 'points' | 'mixed'  // 类型约束确保不遗漏
}

async function createOrder() {
  const request: CreateOrderRequest = {
    items: orderItems.value,
    addressId: selectedAddress.value.id,
    payMethod: payMethod.value,  // TypeScript 会提示缺少字段
  }
  await api.createOrder(request)
}

API 错误处理规范

规则说明
❌ 禁止静默忽略非成功响应res.code !== 200 时必须提示用户
✅ 统一错误提示非成功响应统一 message.error 提示
✅ 网络异常也要处理try/catch 捕获请求异常
// ❌ 只处理成功,非 200 静默忽略
const res = await api.getList(params)
if (res.code === 200) {
  list.value = res.data
}

// ✅ 成功 + 失败都处理
try {
  const res = await api.getList(params)
  if (res.code === 200) {
    list.value = res.data
  } else {
    message.error(res.message || '加载失败')
  }
} catch (e) {
  message.error('网络异常,请稍后重试')
}

类型复用规范

规则说明
❌ 禁止多个文件重复定义相同接口PageResponse、BaseResult 等
✅ 通用类型统一放 @/types/common.ts全局导出,各处引用
// ❌ 每个 api 文件都定义一遍
// api/user.ts
interface PageResponse<T> { list: T[]; total: number }
// api/order.ts
interface PageResponse<T> { list: T[]; total: number } // 重复

// ✅ 统一定义,各处引用
// types/common.ts
export interface PageResponse<T> {
  list: T[]
  total: number
}

// api/user.ts
import type { PageResponse } from '@/types/common'

详细参考

文件内容
references/frontend-style.mdUI 风格、Vue 3 规范、Pinia、API 封装、性能优化
references/miniapp-pitfalls.mduni-app 陷阱:页面栈只读、Storage 清理时机、生命周期双触发、前端校验镜像
references/date-time.mddayjs/date-fns 日期加减、账期计算、禁止月末对齐

📋 本回复遵循:frontend-dev - [具体章节]

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

当设计或修改 REST API 响应结构、处理 API 返回值时触发。防止 API 设计缺陷导致的字段错位、类型歧义等问题。

The English summary is being prepared. Showing the original description.

doccker/cc-use-exp1.1KUpdated Aug 26, 2026

当设计或修改 REST API 响应结构、处理 API 返回值,或生成 Excel/CSV/PDF/对账文件等下游产物时触发。防止 API 设计缺陷导致的字段错位、类型歧义,以及生成产物时关键字段缺失但静默成功的问题。

The English summary is being prepared. Showing the original description.

doccker/cc-use-exp1.1KUpdated Aug 26, 2026

网关/代理/WAF/CDN 中间件的安全关键词匹配实现规范,防止纯子串匹配误判正常响应内容中的技术术语(如 Cloudflare、502、error)

The English summary is being prepared. Showing the original description.

doccker/cc-use-exp1.1KUpdated Aug 26, 2026

当 API/任务可能执行超过 10 秒(批量数据处理、远程 API 批量调用、全表扫描、跨租户聚合)时触发。防止同步接口被网关 30s 超时切断、用户重复点击触发并发、状态缓存内存泄漏等问题。提供异步任务状态机标准模板。

The English summary is being prepared. Showing the original description.

doccker/cc-use-exp1.1KUpdated Aug 26, 2026

Bash 脚本与系统命令规范。禁止行尾注释,强制使用 tee/heredoc 写入,提升命令执行的可维护性。

The English summary is being prepared. Showing the original description.

doccker/cc-use-exp1.1KUpdated Aug 26, 2026

当用户操作 .sh、Dockerfile、Makefile、.yml、.yaml 文件,或在 Markdown 中编写 bash 代码块时触发。提供 Bash 编写规范。

The English summary is being prepared. Showing the original description.

doccker/cc-use-exp1.1KUpdated Aug 26, 2026

See all skills by doccker

Report a problem with this skill