FastAPI+Vue前后端分离架构指南

🚀 FastAPI+Vue前后端分离架构指南

📋 文档概述

本文档详细介绍如何基于现有FastAPI应用构建完整的前后端分离架构,实现现代化的Web应用开发模式。

适用场景:

  • 中小型Web应用开发
  • 快速原型开发和MVP产品
  • 个人项目或小团队协作
  • 需要高性能API的应用

技术栈:

  • 后端:FastAPI + SQLAlchemy + PostgreSQL
  • 前端:Vue 3 + TypeScript + Vite
  • 部署:Docker + Nginx

🏗️ 架构设计

📊 整体架构图

复制代码
┌─────────────────┐    HTTP/WebSocket    ┌─────────────────┐
│   Vue 3 前端     │◄─────────────────────►│  FastAPI 后端    │
│                 │                      │                 │
│ • 用户界面       │                      │ • REST API      │
│ • 状态管理       │                      │ • 业务逻辑       │
│ • 路由导航       │                      │ • 数据验证       │
│ • HTTP客户端     │                      │ • 认证授权       │
└─────────────────┘                      └─────────────────┘
                                                   │
                                         ┌─────────────────┐
                                         │  PostgreSQL     │
                                         │    数据库        │
                                         └─────────────────┘

🎯 架构特点

前后端完全分离:

  • ✅ 前端专注用户体验和界面交互
  • ✅ 后端专注业务逻辑和数据处理
  • ✅ 通过标准HTTP API通信
  • ✅ 独立开发、测试、部署

技术优势:

  • 🚀 高性能:FastAPI异步处理 + Vue响应式更新
  • 📖 自动文档:Swagger UI自动生成API文档
  • 🔒 类型安全:Python类型提示 + TypeScript
  • 🛠️ 开发效率:热重载 + 现代工具链

📁 项目结构

🗂️ 推荐目录结构

复制代码
my-webapp/
├── backend/                     # FastAPI后端服务
│   ├── app/
│   │   ├── __init__.py
│   │   ├── main.py             # FastAPI应用入口
│   │   ├── models/             # 数据模型
│   │   │   ├── __init__.py
│   │   │   ├── user.py
│   │   │   └── base.py
│   │   ├── schemas/            # Pydantic模式
│   │   │   ├── __init__.py
│   │   │   └── user.py
│   │   ├── api/                # API路由
│   │   │   ├── __init__.py
│   │   │   ├── deps.py         # 依赖注入
│   │   │   └── endpoints/
│   │   │       ├── auth.py
│   │   │       ├── users.py
│   │   │       └── files.py
│   │   ├── core/               # 核心配置
│   │   │   ├── __init__.py
│   │   │   ├── config.py
│   │   │   └── security.py
│   │   └── db/                 # 数据库
│   │       ├── __init__.py
│   │       ├── database.py
│   │       └── session.py
│   ├── requirements.txt
│   ├── Dockerfile
│   └── alembic/               # 数据库迁移
├── frontend/                   # Vue前端应用
│   ├── public/
│   ├── src/
│   │   ├── main.ts            # 应用入口
│   │   ├── App.vue            # 根组件
│   │   ├── components/        # 可复用组件
│   │   │   ├── common/
│   │   │   └── ui/
│   │   ├── views/             # 页面组件
│   │   │   ├── Home.vue
│   │   │   ├── Login.vue
│   │   │   └── Dashboard.vue
│   │   ├── router/            # 路由配置
│   │   │   └── index.ts
│   │   ├── stores/            # 状态管理
│   │   │   ├── auth.ts
│   │   │   └── user.ts
│   │   ├── services/          # API服务
│   │   │   ├── api.ts
│   │   │   ├── auth.ts
│   │   │   └── types.ts
│   │   └── utils/             # 工具函数
│   ├── package.json
│   ├── vite.config.ts
│   ├── tsconfig.json
│   └── Dockerfile
├── docker-compose.yml          # 容器编排
├── nginx.conf                  # 反向代理配置
└── README.md

🔧 后端开发指南

📝 基于现有FastAPI应用扩展

1. 项目结构重构

基于你现有的 fastapi_demo.py,我们需要将代码模块化:

python 复制代码
# backend/app/main.py - 应用入口
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.api.endpoints import auth, users, files
from app.core.config import settings

app = FastAPI(
    title="现代化Web应用API",
    description="基于FastAPI的高性能后端服务",
    version="1.0.0"
)

# CORS配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.ALLOWED_HOSTS,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 包含路由
app.include_router(auth.router, prefix="/api/auth", tags=["认证"])
app.include_router(users.router, prefix="/api/users", tags=["用户管理"])
app.include_router(files.router, prefix="/api/files", tags=["文件操作"])

@app.get("/")
async def root():
    return {"message": "FastAPI + Vue 前后端分离应用"}

2. 数据模型设计

python 复制代码
# backend/app/models/user.py
from sqlalchemy import Column, Integer, String, DateTime, Boolean
from sqlalchemy.ext.declarative import declarative_base
from datetime import datetime

Base = declarative_base()

class User(Base):
    __tablename__ = "users"
  
    id = Column(Integer, primary_key=True, index=True)
    email = Column(String, unique=True, index=True, nullable=False)
    name = Column(String, nullable=False)
    hashed_password = Column(String, nullable=False)
    is_active = Column(Boolean, default=True)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

3. Pydantic模式定义

python 复制代码
# backend/app/schemas/user.py
from pydantic import BaseModel, EmailStr
from datetime import datetime
from typing import Optional

class UserBase(BaseModel):
    email: EmailStr
    name: str
    is_active: bool = True

class UserCreate(UserBase):
    password: str

class UserUpdate(BaseModel):
    email: Optional[EmailStr] = None
    name: Optional[str] = None
    is_active: Optional[bool] = None

class UserResponse(UserBase):
    id: int
    created_at: datetime
    updated_at: datetime
  
    class Config:
        from_attributes = True

class UserLogin(BaseModel):
    email: EmailStr
    password: str

class Token(BaseModel):
    access_token: str
    token_type: str = "bearer"

4. API端点实现

python 复制代码
# backend/app/api/endpoints/users.py
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import List

from app.schemas.user import UserCreate, UserResponse, UserUpdate
from app.api.deps import get_db, get_current_user
from app.models.user import User
from app.core.security import get_password_hash

router = APIRouter()

@router.get("/", response_model=List[UserResponse])
async def get_users(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取用户列表"""
    users = db.query(User).offset(skip).limit(limit).all()
    return users

@router.post("/", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
async def create_user(
    user: UserCreate,
    db: Session = Depends(get_db)
):
    """创建新用户"""
    # 检查邮箱是否已存在
    if db.query(User).filter(User.email == user.email).first():
        raise HTTPException(
            status_code=400,
            detail="邮箱已被注册"
        )
  
    # 创建用户
    db_user = User(
        email=user.email,
        name=user.name,
        hashed_password=get_password_hash(user.password),
        is_active=user.is_active
    )
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user

@router.get("/{user_id}", response_model=UserResponse)
async def get_user(
    user_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取用户详情"""
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    return user

5. 认证系统

python 复制代码
# backend/app/api/endpoints/auth.py
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session

from app.schemas.user import Token, UserCreate, UserResponse
from app.api.deps import get_db
from app.core.security import verify_password, create_access_token
from app.models.user import User

router = APIRouter()

@router.post("/login", response_model=Token)
async def login(
    form_data: OAuth2PasswordRequestForm = Depends(),
    db: Session = Depends(get_db)
):
    """用户登录"""
    user = db.query(User).filter(User.email == form_data.username).first()
  
    if not user or not verify_password(form_data.password, user.hashed_password):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="邮箱或密码错误",
            headers={"WWW-Authenticate": "Bearer"},
        )
  
    access_token = create_access_token(data={"sub": user.email})
    return {"access_token": access_token, "token_type": "bearer"}

@router.post("/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
async def register(
    user: UserCreate,
    db: Session = Depends(get_db)
):
    """用户注册"""
    # 检查邮箱是否已存在
    if db.query(User).filter(User.email == user.email).first():
        raise HTTPException(
            status_code=400,
            detail="邮箱已被注册"
        )
  
    # 创建用户
    db_user = User(
        email=user.email,
        name=user.name,
        hashed_password=get_password_hash(user.password)
    )
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user

🎨 前端开发指南

📝 Vue 3 + TypeScript项目搭建

1. 项目初始化

bash 复制代码
# 创建Vue项目
npm create vue@latest frontend
cd frontend

# 选择配置
✅ TypeScript
✅ Router
✅ Pinia (状态管理)
✅ ESLint
✅ Prettier

# 安装依赖
npm install
npm install axios @types/axios
npm install element-plus  # UI组件库
npm install @element-plus/icons-vue

2. API服务配置

typescript 复制代码
// frontend/src/services/api.ts
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { useAuthStore } from '@/stores/auth'

class ApiService {
  private api: AxiosInstance

  constructor() {
    this.api = axios.create({
      baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000',
      timeout: 10000,
      headers: {
        'Content-Type': 'application/json',
      }
    })

    // 请求拦截器 - 添加认证token
    this.api.interceptors.request.use(
      (config) => {
        const authStore = useAuthStore()
        if (authStore.token) {
          config.headers.Authorization = `Bearer ${authStore.token}`
        }
        return config
      },
      (error) => Promise.reject(error)
    )

    // 响应拦截器 - 处理错误
    this.api.interceptors.response.use(
      (response) => response,
      (error) => {
        if (error.response?.status === 401) {
          const authStore = useAuthStore()
          authStore.logout()
        }
        return Promise.reject(error)
      }
    )
  }

  // 通用请求方法
  async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
    const response: AxiosResponse<T> = await this.api.get(url, config)
    return response.data
  }

  async post<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
    const response: AxiosResponse<T> = await this.api.post(url, data, config)
    return response.data
  }

  async put<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
    const response: AxiosResponse<T> = await this.api.put(url, data, config)
    return response.data
  }

  async delete<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
    const response: AxiosResponse<T> = await this.api.delete(url, config)
    return response.data
  }
}

export const apiService = new ApiService()

3. 类型定义

typescript 复制代码
// frontend/src/services/types.ts
export interface User {
  id: number
  email: string
  name: string
  is_active: boolean
  created_at: string
  updated_at: string
}

export interface UserCreate {
  email: string
  name: string
  password: string
}

export interface UserLogin {
  email: string
  password: string
}

export interface Token {
  access_token: string
  token_type: string
}

export interface ApiResponse<T> {
  data: T
  message?: string
  status: string
}

4. 认证状态管理

typescript 复制代码
// frontend/src/stores/auth.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import type { User, UserLogin, Token } from '@/services/types'
import { apiService } from '@/services/api'

export const useAuthStore = defineStore('auth', () => {
  // 状态
  const token = ref<string | null>(localStorage.getItem('token'))
  const user = ref<User | null>(null)
  const isLoading = ref(false)

  // 计算属性
  const isAuthenticated = computed(() => !!token.value)

  // 登录
  async function login(credentials: UserLogin) {
    try {
      isLoading.value = true
      const response = await apiService.post<Token>('/api/auth/login', credentials)
    
      token.value = response.access_token
      localStorage.setItem('token', response.access_token)
    
      // 获取用户信息
      await getCurrentUser()
    
      return { success: true }
    } catch (error: any) {
      console.error('登录失败:', error)
      return { 
        success: false, 
        message: error.response?.data?.detail || '登录失败' 
      }
    } finally {
      isLoading.value = false
    }
  }

  // 获取当前用户信息
  async function getCurrentUser() {
    try {
      user.value = await apiService.get<User>('/api/auth/me')
    } catch (error) {
      console.error('获取用户信息失败:', error)
      logout()
    }
  }

  // 登出
  function logout() {
    token.value = null
    user.value = null
    localStorage.removeItem('token')
  }

  // 注册
  async function register(userData: UserCreate) {
    try {
      isLoading.value = true
      await apiService.post('/api/auth/register', userData)
      return { success: true }
    } catch (error: any) {
      return { 
        success: false, 
        message: error.response?.data?.detail || '注册失败' 
      }
    } finally {
      isLoading.value = false
    }
  }

  return {
    token,
    user,
    isLoading,
    isAuthenticated,
    login,
    logout,
    register,
    getCurrentUser
  }
})

5. 路由配置

typescript 复制代码
// frontend/src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import { useAuthStore } from '@/stores/auth'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: () => import('@/views/Home.vue')
    },
    {
      path: '/login',
      name: 'login',
      component: () => import('@/views/Login.vue')
    },
    {
      path: '/dashboard',
      name: 'dashboard',
      component: () => import('@/views/Dashboard.vue'),
      meta: { requiresAuth: true }
    },
    {
      path: '/users',
      name: 'users',
      component: () => import('@/views/Users.vue'),
      meta: { requiresAuth: true }
    }
  ]
})

// 路由守卫
router.beforeEach((to, from, next) => {
  const authStore = useAuthStore()
  
  if (to.meta.requiresAuth && !authStore.isAuthenticated) {
    next('/login')
  } else {
    next()
  }
})

export default router

6. Vue组件示例

vue 复制代码
<!-- frontend/src/views/Users.vue -->
<template>
  <div class="users-page">
    <div class="header">
      <h1>用户管理</h1>
      <el-button type="primary" @click="showCreateDialog = true">
        <el-icon><Plus /></el-icon>
        添加用户
      </el-button>
    </div>

    <!-- 用户列表 -->
    <el-table :data="users" v-loading="loading" stripe>
      <el-table-column prop="id" label="ID" width="80" />
      <el-table-column prop="name" label="姓名" />
      <el-table-column prop="email" label="邮箱" />
      <el-table-column prop="is_active" label="状态">
        <template #default="{ row }">
          <el-tag :type="row.is_active ? 'success' : 'danger'">
            {{ row.is_active ? '激活' : '禁用' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="created_at" label="创建时间">
        <template #default="{ row }">
          {{ formatDate(row.created_at) }}
        </template>
      </el-table-column>
      <el-table-column label="操作" width="200">
        <template #default="{ row }">
          <el-button size="small" @click="editUser(row)">编辑</el-button>
          <el-button size="small" type="danger" @click="deleteUser(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <el-pagination
      v-model:current-page="currentPage"
      v-model:page-size="pageSize"
      :total="total"
      :page-sizes="[10, 20, 50, 100]"
      layout="total, sizes, prev, pager, next, jumper"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />

    <!-- 创建用户对话框 -->
    <el-dialog v-model="showCreateDialog" title="添加用户" width="500px">
      <el-form :model="createForm" :rules="rules" ref="createFormRef" label-width="80px">
        <el-form-item label="姓名" prop="name">
          <el-input v-model="createForm.name" />
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="createForm.email" />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input v-model="createForm.password" type="password" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showCreateDialog = false">取消</el-button>
        <el-button type="primary" @click="createUser" :loading="creating">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import type { User, UserCreate } from '@/services/types'
import { apiService } from '@/services/api'

// 响应式数据
const users = ref<User[]>([])
const loading = ref(false)
const creating = ref(false)
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
const showCreateDialog = ref(false)

// 表单数据
const createForm = ref<UserCreate>({
  name: '',
  email: '',
  password: ''
})

// 表单验证规则
const rules = {
  name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
  email: [
    { required: true, message: '请输入邮箱', trigger: 'blur' },
    { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
  ],
  password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
}

// 获取用户列表
async function fetchUsers() {
  try {
    loading.value = true
    const response = await apiService.get<User[]>(`/api/users/?skip=${(currentPage.value - 1) * pageSize.value}&limit=${pageSize.value}`)
    users.value = response
  } catch (error) {
    ElMessage.error('获取用户列表失败')
  } finally {
    loading.value = false
  }
}

// 创建用户
async function createUser() {
  try {
    creating.value = true
    await apiService.post('/api/users/', createForm.value)
    ElMessage.success('用户创建成功')
    showCreateDialog.value = false
    createForm.value = { name: '', email: '', password: '' }
    fetchUsers()
  } catch (error: any) {
    ElMessage.error(error.response?.data?.detail || '创建用户失败')
  } finally {
    creating.value = false
  }
}

// 删除用户
async function deleteUser(user: User) {
  try {
    await ElMessageBox.confirm(`确定要删除用户 "${user.name}" 吗?`, '确认删除', {
      type: 'warning'
    })
  
    await apiService.delete(`/api/users/${user.id}`)
    ElMessage.success('用户删除成功')
    fetchUsers()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除用户失败')
    }
  }
}

// 格式化日期
function formatDate(dateString: string) {
  return new Date(dateString).toLocaleString('zh-CN')
}

// 分页处理
function handleSizeChange(size: number) {
  pageSize.value = size
  fetchUsers()
}

function handleCurrentChange(page: number) {
  currentPage.value = page
  fetchUsers()
}

// 组件挂载时获取数据
onMounted(() => {
  fetchUsers()
})
</script>

<style scoped>
.users-page {
  padding: 20px;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.el-pagination {
  margin-top: 20px;
  justify-content: center;
}
</style>

🚀 部署配置

📦 Docker容器化

1. 后端Dockerfile

dockerfile 复制代码
# backend/Dockerfile
FROM python:3.11-slim

WORKDIR /app

# 安装系统依赖
RUN apt-get update && apt-get install -y \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# 复制依赖文件
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 8000

# 启动命令
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

2. 前端Dockerfile

dockerfile 复制代码
# frontend/Dockerfile
# 构建阶段
FROM node:18-alpine as build-stage

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

COPY . .
RUN npm run build

# 生产阶段
FROM nginx:alpine as production-stage

COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

3. Docker Compose配置

yaml 复制代码
# docker-compose.yml
version: '3.8'

services:
  # PostgreSQL数据库
  db:
    image: postgres:15
    environment:
      POSTGRES_DB: webapp_db
      POSTGRES_USER: webapp_user
      POSTGRES_PASSWORD: webapp_pass
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  # Redis缓存
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

  # FastAPI后端
  backend:
    build: ./backend
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://webapp_user:webapp_pass@db:5432/webapp_db
      - REDIS_URL=redis://redis:6379
    depends_on:
      - db
      - redis
    volumes:
      - ./backend:/app
    command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload

  # Vue前端
  frontend:
    build: ./frontend
    ports:
      - "8080:80"
    environment:
      - VITE_API_BASE_URL=http://localhost:8000
    depends_on:
      - backend

  # Nginx反向代理
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - frontend
      - backend

volumes:
  postgres_data:

4. Nginx配置

nginx 复制代码
# nginx.conf
events {
    worker_connections 1024;
}

http {
    upstream backend {
        server backend:8000;
    }
  
    upstream frontend {
        server frontend:80;
    }

    server {
        listen 80;
      
        # API请求转发到后端
        location /api/ {
            proxy_pass http://backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
      
        # 文档页面转发到后端
        location /docs {
            proxy_pass http://backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
      
        location /redoc {
            proxy_pass http://backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
      
        # 前端页面
        location / {
            proxy_pass http://frontend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

🛠️ 开发工作流

📋 开发步骤

1. 环境准备

bash 复制代码
# 克隆项目
git clone <your-repo>
cd my-webapp

# 启动开发环境
docker-compose up -d db redis
cd backend && pip install -r requirements.txt
cd ../frontend && npm install

2. 后端开发

bash 复制代码
# 启动后端开发服务器
cd backend
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

# 数据库迁移
alembic upgrade head

# 访问API文档
# http://localhost:8000/docs

3. 前端开发

bash 复制代码
# 启动前端开发服务器
cd frontend
npm run dev

# 访问应用
# http://localhost:3000

4. 联调测试

bash 复制代码
# 同时启动前后端服务
# 前端会自动代理API请求到后端
# 支持热重载和实时调试

🔧 调试技巧

后端调试:

  • 使用FastAPI的自动文档进行API测试
  • 配置日志记录和错误追踪
  • 使用Pydantic进行数据验证

前端调试:

  • 使用Vue DevTools浏览器扩展
  • 配置代理解决跨域问题
  • 使用TypeScript获得类型检查

📈 性能优化

⚡ 后端优化

1. 数据库优化

python 复制代码
# 使用连接池
from sqlalchemy.pool import QueuePool

engine = create_engine(
    DATABASE_URL,
    poolclass=QueuePool,
    pool_size=20,
    max_overflow=30
)

# 查询优化
@router.get("/users/")
async def get_users(
    db: Session = Depends(get_db)
):
    # 使用索引和预加载
    return db.query(User).options(
        selectinload(User.profile)
    ).filter(User.is_active == True).all()

2. 缓存策略

python 复制代码
from fastapi_cache import FastAPICache
from fastapi_cache.backends.redis import RedisBackend

# Redis缓存配置
@app.on_event("startup")
async def startup():
    redis = aioredis.from_url("redis://localhost:6379")
    FastAPICache.init(RedisBackend(redis), prefix="fastapi-cache")

# 使用缓存
@cache(expire=300)  # 5分钟缓存
@router.get("/users/stats")
async def get_user_stats():
    # 计算密集型操作
    return calculate_user_statistics()

🎨 前端优化

1. 代码分割

typescript 复制代码
// 路由懒加载
const router = createRouter({
  routes: [
    {
      path: '/users',
      component: () => import('@/views/Users.vue')  // 懒加载
    }
  ]
})

// 组件懒加载
import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() => import('./Component.vue'))

2. 状态管理优化

typescript 复制代码
// 使用Pinia持久化
import { createPersistedState } from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(createPersistedState({
  storage: sessionStorage,  // 使用sessionStorage
  paths: ['auth.token']     // 只持久化必要数据
}))

🚀 快速开始

📋 基于现有FastAPI应用改造

如果你已有FastAPI应用(如 fastapi_demo.py),可以按以下步骤快速改造:

步骤1:重构后端代码

bash 复制代码
# 1. 创建新的项目结构
mkdir -p backend/app/{api,core,db,models,schemas}

# 2. 将现有代码按模块拆分
# 将用户相关代码移到 app/api/endpoints/users.py
# 将模型定义移到 app/models/
# 将配置移到 app/core/config.py

步骤2:创建Vue前端

bash 复制代码
# 1. 创建Vue项目
npm create vue@latest frontend

# 2. 配置API服务和状态管理
# 参考上面的代码示例

步骤3:容器化部署

bash 复制代码
# 1. 创建Dockerfile和docker-compose.yml
# 2. 启动完整环境
docker-compose up -d

📚 总结

✅ 架构优势

开发效率:

  • 🚀 前后端并行开发
  • 📖 自动API文档生成
  • 🔄 热重载开发体验
  • 🛠️ 现代化工具链

技术优势:

  • ⚡ 高性能异步处理
  • 🔒 类型安全保障
  • 📱 响应式用户界面
  • 🐳 容器化部署

维护优势:

  • 🔧 代码结构清晰
  • 🧪 易于测试
  • 📈 便于扩展
  • 🔍 问题定位简单

📋 适用场景

推荐使用:

  • ✅ 中小型Web应用
  • ✅ 快速原型开发
  • ✅ API优先的项目
  • ✅ 需要现代化UI的应用

不推荐使用:

  • ❌ 简单的静态网站
  • ❌ 传统企业内部系统
  • ❌ 对SEO要求极高的网站

🎯 下一步建议

  1. 学习路径:先掌握FastAPI基础,再学习Vue 3
  2. 实践项目:从简单的CRUD应用开始
  3. 逐步优化:添加认证、缓存、监控等功能
  4. 生产部署:学习Docker、CI/CD等运维知识

这种架构非常适合现代Web应用开发,结合你已有的FastAPI基础,可以快速构建出高质量的前后端分离应用!


文档版本:v1.0 | 创建日期:2025-09-24 | 基于FastAPI演示工具扩展

相关推荐
大咖分享课6 小时前
双活、异地多活架构怎么设计才不翻车?
架构·两地三中心·多活架构
云宏信息6 小时前
赛迪顾问《2025中国虚拟化市场研究报告》解读丨虚拟化市场迈向“多元算力架构”,国产化与AI驱动成关键变量
网络·人工智能·ai·容器·性能优化·架构·云计算
正义的大古7 小时前
OpenLayers地图交互 -- 章节七:指针交互详解
前端·javascript·vue.js·openlayers
qwy7152292581637 小时前
vue自定义指令
前端·javascript·vue.js
看到我请叫我铁锤7 小时前
vue3使用leaflet的时候高亮显示省市区
前端·javascript·vue.js
代码代码快快显灵8 小时前
Axios的基本知识点以及vue的开发工程(基于大事件)详细解释
前端·javascript·vue.js
IT酷盖8 小时前
Android解决隐藏依赖冲突
android·前端·vue.js
Juchecar9 小时前
翻译:为什么 本地优先应用 没有流行开来?
架构
小噔小咚什么东东9 小时前
Vue开发H5项目中基于栈的弹窗管理
前端·vue.js·vant