网页端开发规范 (Web Development)
定位:FastAPI + Vue 3 全栈 Web 开发标准,确保前后端协作高效、代码规范统一。
技术选型
后端
| 层级 |
技术栈 |
版本要求 |
选型理由 |
| Web 框架 |
FastAPI |
≥ 0.100 |
异步优先、自动文档 |
| ORM |
SQLAlchemy |
2.0+ |
异步支持、成熟生态 |
| 数据库 |
MySQL |
8.0+ |
事务支持、成熟稳定 |
前端
| 层级 |
技术栈 |
版本要求 |
选型理由 |
| 构建工具 |
Vite |
≥ 5.0 |
热更新秒级体验 |
| 框架 |
Vue 3 |
≥ 3.3 |
Composition API |
| 类型系统 |
TypeScript |
≥ 5.0 |
类型安全 |
| 状态管理 |
Pinia |
≥ 2.0 |
轻量、TS 支持好 |
| UI 组件库 |
Element Plus |
≥ 2.0 |
企业级组件库 |
| 包管理 |
pnpm |
≥ 8.0 |
磁盘空间高效 |
项目结构
后端 (src/)
src/
├── core/ # 核心基础设施
│ ├── config.py # 配置管理
│ ├── database.py # 数据库连接池
│ └── models.py # ORM 模型定义
├── service/ # 业务逻辑层(强制路由)
├── api/ # 路由层
├── schemas/ # Pydantic 模型
├── LLM/ # LLM 集成
└── utils/ # 工具函数
前端 (web/)
web/
├── src/
│ ├── api/ # API 接口层
│ ├── components/ # 组件
│ ├── composables/ # 组合式函数
│ ├── stores/ # Pinia 状态管理
│ ├── views/ # 页面组件
│ └── router/ # 路由配置
├── public/ # 静态资源
└── vite.config.ts
前后端协作规范
API 响应格式
# 后端统一响应结构
class Response(BaseModel):
code: int = 0
message: str = "success"
data: T | None = None
API 调用封装
// 前端 API 层
import { request } from '@/utils/request'
export const userApi = {
getUser: (id: number) => request.get<UserInfo>(`/users/${id}`),
updateUser: (data: UserUpdate) => request.put<UserInfo>('/users', data),
}
错误处理
| HTTP 状态码 |
前端处理 |
| 400 |
显示错误提示 |
| 401 |
跳转登录页 |
| 403 |
显示无权限提示 |
| 404 |
显示不存在提示 |
| 500 |
显示服务器错误 |
布局规范
全屏容器
.page-container {
width: 100%;
min-height: 100vh;
margin: 0;
box-sizing: border-box;
}
盒模型
/* 全局启用 */
*, *::before, *::after {
box-sizing: border-box;
}
滚动策略
| 规则 |
说明 |
| 页面级滚动 |
使用原生滚动,禁止容器内 overflow: auto |
| 表格滚动 |
禁止表格内固定高度滚动 |
| 虚拟滚动 |
大列表使用虚拟滚动组件 |
表格规范
Element Plus 表格
<template>
<el-table :data="tableData" stripe>
<el-table-column prop="name" label="名称" min-width="120" />
<el-table-column prop="status" label="状态">
<template #default="{ row }">
<el-tag :type="row.status === 1 ? 'success' : 'info'">
{{ row.status === 1 ? '启用' : '禁用' }}
</el-tag>
</template>
</el-table-column>
</el-table>
</template>
| 属性 |
要求 |
stripe |
必须开启,提升可读性 |
min-width |
列宽使用 min-width 而非 width |
show-overflow-tooltip |
长文本必须开启 |
栅格系统
必须使用 el-row / el-col
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="名称">
<el-input v-model="form.name" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态">
<el-select v-model="form.status" />
</el-form-item>
</el-col>
</el-row>
文件上传陷阱
handleFileChange(e: Event) {
const target = e.target as HTMLInputElement
const file = target.files?.[0]
if (!file) return
// 处理上传逻辑...
// 必须重置,否则重复选择同一文件不触发
target.value = ''
}
Markdown 渲染
const renderMarkdown = (text: string): string => {
if (!text) return ''
let html = text
.replace(/\n/g, '<br>')
.replace(/<br>- /g, '<br><span class="md-list-item">• </span>')
.replace(/`([^`]+)`/g, '<code class="md-code">$1</code>')
return html
}
.md-list-item {
color: #409eff;
font-weight: bold;
margin-right: 4px;
}
.md-code {
background: #f4f4f5;
padding: 2px 6px;
border-radius: 3px;
font-family: monospace;
}
样式规范
命名约定
| 类型 |
前缀 |
示例 |
| 布局 |
l- |
l-container |
| 组件 |
c- |
c-button |
| 工具 |
u- |
u-flex-center |
| 状态 |
is- |
is-active |
CSS 变量
:root {
--color-primary: #409eff;
--color-success: #67c23a;
--color-warning: #e6a23c;
--color-danger: #f56c6c;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
}
性能优化
| 策略 |
说明 |
| 路由懒加载 |
使用动态 import |
| 组件懒加载 |
大组件异步加载 |
| 图片懒加载 |
使用 loading="lazy" |
| CDN 加速 |
静态资源上 CDN |
| Gzip 压缩 |
服务器开启 Gzip |
常见陷阱
| 问题 |
原因 |
解法 |
| 表格高度异常 |
容器设置 height: 100% |
使用 min-height 或不设高度 |
| 栅格错位 |
未使用 el-row 包裹 |
必须使用 el-row + el-col |
| 文件重复选择失效 |
未重置 input |
e.target.value = '' |
| 样式污染 |
未使用 scoped |
添加 scoped 属性 |
沉淀协议
| 场景 |
行动 |
| 布局模式重复 ≥ 3 次 |
封装为布局组件 |
| 样式规范固化 |
更新本文档 |
| 前后端协议变更 |
同步更新双方文档 |