fastapi-demo/docs/frontend-ui/DESIGN_frontend-ui.md

8.4 KiB

DESIGN - 前端 UI 项目架构设计

🏗️ 整体架构图

graph TB
    subgraph "前端项目 (localhost:3000)"
        A[Vue 3 App] --> B[Vue Router]
        A --> C[Element Plus UI]
        A --> D[Axios HTTP Client]

        B --> E[Dashboard View]
        B --> F[User Management View]
        B --> G[Product Management View]

        F --> H[User List Component]
        F --> I[User Form Component]

        G --> J[Product List Component]
        G --> K[Product Form Component]

        H --> L[Table Component]
        I --> M[Form Component]
        J --> L
        K --> M

        D --> N[API Service Layer]
        N --> O[User API]
        N --> P[Product API]
    end

    subgraph "后端项目 (localhost:8000)"
        Q[FastAPI App]
        R[User Endpoints]
        S[Product Endpoints]
        T[MySQL Database]

        Q --> R
        Q --> S
        R --> T
        S --> T
    end

    O -.->|HTTP Requests| R
    P -.->|HTTP Requests| S

    style A fill:#42b883
    style Q fill:#009688
    style T fill:#336791

🏛️ 分层设计

1. 表现层 (Presentation Layer)

  • Views/Pages: 页面级组件,对应路由
  • Components: 可复用的 UI 组件
  • Layout: 布局组件 (侧边栏、头部、内容区域)

2. 服务层 (Service Layer)

  • API Services: HTTP 请求封装
  • Utils: 通用工具函数
  • Constants: 常量定义

3. 路由层 (Router Layer)

  • Route Configuration: 路由配置
  • Navigation Guards: 路由守卫 (如需要)

4. 状态层 (State Layer)

  • Local State: 组件内部状态 (Composition API)
  • Props/Emit: 组件间通信

📦 核心组件设计

布局组件

graph TB
    A[AppLayout] --> B[AppHeader]
    A --> C[AppSidebar]
    A --> D[AppMain]

    B --> E[Logo]
    B --> F[User Info]

    C --> G[Navigation Menu]
    G --> H[Dashboard Link]
    G --> I[Users Link]
    G --> J[Products Link]

    D --> K[Router View]

页面组件架构

graph TB
    subgraph "用户管理页面"
        A[UserManagement] --> B[UserList]
        A --> C[UserDialog]
        B --> D[DataTable]
        B --> E[TableActions]
        C --> F[UserForm]
        C --> G[FormActions]
    end

    subgraph "产品管理页面"
        H[ProductManagement] --> I[ProductList]
        H --> J[ProductDialog]
        I --> K[DataTable]
        I --> L[TableActions]
        J --> M[ProductForm]
        J --> N[FormActions]
    end

🔌 接口契约定义

API Service 接口

// api/user.js
export const userAPI = {
  // 获取用户列表
  getUsers: () => axios.get('/api/v1/users/'),

  // 获取单个用户
  getUser: (id) => axios.get(`/api/v1/users/${id}`),

  // 创建用户
  createUser: (userData) => axios.post('/api/v1/users/', userData),

  // 更新用户
  updateUser: (id, userData) => axios.put(`/api/v1/users/${id}`, userData),

  // 删除用户
  deleteUser: (id) => axios.delete(`/api/v1/users/${id}`)
}

// api/product.js
export const productAPI = {
  // 获取产品列表
  getProducts: () => axios.get('/api/v1/products/'),

  // 获取单个产品
  getProduct: (id) => axios.get(`/api/v1/products/${id}`),

  // 创建产品
  createProduct: (productData) => axios.post('/api/v1/products/', productData),

  // 更新产品
  updateProduct: (id, productData) => axios.put(`/api/v1/products/${id}`, productData),

  // 删除产品
  deleteProduct: (id) => axios.delete(`/api/v1/products/${id}`)
}

组件 Props 接口

// components/DataTable.vue Props
interface DataTableProps {
  data: Array<Object>      // 表格数据
  columns: Array<Object>   // 列配置
  loading: Boolean         // 加载状态
  actions: Array<Object>   // 操作按钮配置
}

// components/UserForm.vue Props
interface UserFormProps {
  user: Object | null      // 用户数据 (编辑模式)
  mode: 'create' | 'edit'  // 表单模式
  loading: Boolean         // 提交状态
}

// components/ProductForm.vue Props
interface ProductFormProps {
  product: Object | null   // 产品数据 (编辑模式)
  mode: 'create' | 'edit'  // 表单模式
  loading: Boolean         // 提交状态
}

📊 数据流向图

sequenceDiagram
    participant U as User
    participant V as Vue Component
    participant A as API Service
    participant B as Backend API
    participant D as Database

    U->>V: 用户操作 (点击、提交)
    V->>A: 调用 API 方法
    A->>B: HTTP 请求
    B->>D: 数据库操作
    D-->>B: 返回数据
    B-->>A: HTTP 响应
    A-->>V: 返回结果
    V-->>U: 更新界面

🚨 异常处理策略

HTTP 错误处理

// utils/request.js - Axios 拦截器
axios.interceptors.response.use(
  response => response,
  error => {
    const { status, data } = error.response

    switch (status) {
      case 400:
        ElMessage.error(data.detail || '请求参数错误')
        break
      case 404:
        ElMessage.error('资源不存在')
        break
      case 409:
        ElMessage.error(data.detail || '数据冲突')
        break
      case 500:
        ElMessage.error('服务器内部错误')
        break
      default:
        ElMessage.error('网络连接异常')
    }

    return Promise.reject(error)
  }
)

表单验证策略

// 用户表单验证规则
const userFormRules = {
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 3, max: 20, message: '用户名长度为 3-20 个字符', trigger: 'blur' }
  ],
  email: [
    { required: true, message: '请输入邮箱地址', trigger: 'blur' },
    { type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
  ]
}

// 产品表单验证规则
const productFormRules = {
  name: [
    { required: true, message: '请输入产品名称', trigger: 'blur' },
    { min: 2, max: 50, message: '产品名称长度为 2-50 个字符', trigger: 'blur' }
  ],
  price: [
    { required: true, message: '请输入产品价格', trigger: 'blur' },
    { type: 'number', min: 0, message: '价格必须大于等于 0', trigger: 'blur' }
  ],
  stock: [
    { required: true, message: '请输入库存数量', trigger: 'blur' },
    { type: 'integer', min: 0, message: '库存必须为非负整数', trigger: 'blur' }
  ]
}

📱 响应式设计

断点设计

/* 响应式断点 */
/* 手机端 */
@media (max-width: 768px) {
  .sidebar { display: none; }
  .main-content { margin-left: 0; }
}

/* 平板端 */
@media (min-width: 769px) and (max-width: 1024px) {
  .sidebar { width: 200px; }
  .main-content { margin-left: 200px; }
}

/* 桌面端 */
@media (min-width: 1025px) {
  .sidebar { width: 250px; }
  .main-content { margin-left: 250px; }
}

组件响应式

  • 表格组件支持横向滚动
  • 表单组件自适应布局
  • 按钮组合在小屏幕下垂直排列

🛠️ 开发环境配置

Vite 配置

// vite.config.js
export default {
  server: {
    port: 3000,
    proxy: {
      '/api': {
        target: 'http://localhost:8000',
        changeOrigin: true
      }
    }
  },
  build: {
    outDir: 'dist',
    assetsDir: 'assets'
  }
}

环境变量

# .env.development
VITE_API_BASE_URL=http://localhost:8000
VITE_APP_TITLE=FastAPI Demo - 管理后台

# .env.production
VITE_API_BASE_URL=https://your-api-domain.com
VITE_APP_TITLE=FastAPI Demo - 管理后台

🔄 组件生命周期设计

页面组件生命周期

// views/UserManagement.vue
export default {
  setup() {
    const users = ref([])
    const loading = ref(false)

    // 页面加载时获取数据
    onMounted(async () => {
      await loadUsers()
    })

    const loadUsers = async () => {
      loading.value = true
      try {
        const response = await userAPI.getUsers()
        users.value = response.data
      } catch (error) {
        console.error('加载用户失败:', error)
      } finally {
        loading.value = false
      }
    }

    return {
      users,
      loading,
      loadUsers
    }
  }
}

📋 组件复用策略

通用组件设计

  1. DataTable: 通用数据表格组件
  2. FormDialog: 通用表单对话框组件
  3. ConfirmDialog: 通用确认对话框组件
  4. LoadingOverlay: 通用加载覆盖层组件
  5. EmptyState: 通用空状态组件

业务组件设计

  1. UserForm: 用户表单组件
  2. ProductForm: 产品表单组件
  3. UserList: 用户列表组件
  4. ProductList: 产品列表组件