AI全栈开发入门:FastAPI与Vue3构建前后端分离应用
1. 项目概述:从“第一周”到技术栈全景
“第一周概述”这个标题,乍一看有点模糊,像是某个课程、训练营或者个人学习计划的起始章节。但结合我们手头的热搜词和网络热词,这个“第一周”的轮廓就清晰多了。它指向的是一个以AI应用开发为核心,融合了前端(Vue)、后端(FastAPI/Python)的现代全栈技术学习或实战项目的开端。这不仅仅是“Hello World”,而是一个从零到一,构建一个具备AI能力、前后端分离的完整应用的第一块基石。
我自己带过不少新人项目,也经历过无数次从零开始的“第一周”。这个阶段最关键的,不是急于敲出多少行代码,而是建立起清晰的技术全景图和可落地的开发路径。很多人一上来就埋头学Python语法或者Vue组件,学了两周发现前后端连不上,AI模型不知道怎么集成,项目结构一团糟。所以,这个“概述”的价值,在于帮你避开这些坑,从一开始就用工程化的思维去规划。
简单来说,这个“第一周”的目标是:搭建一个最小可行(MVP)的技术骨架。这个骨架要能支撑起一个典型的AI应用,比如一个智能对话助手、一个基于AI的图片处理工具,或者一个数据分析仪表盘。它的核心任务包括:确立前后端技术选型(为什么是FastAPI和Vue)、配置好本地开发环境、创建最基本的项目结构,并实现一个“心跳接口”——让前端能成功调用后端的一个简单接口。这听起来基础,但却是后续所有复杂功能(如AI模型集成、用户认证、数据管理)得以平稳扩展的前提。
2. 技术选型与架构设计思路
为什么是FastAPI + Vue?这不是随大流,而是基于现代Web开发效率、性能和学习曲线综合考量后的结果。我们先拆开看每个部分的选择逻辑。
2.1 后端:为什么是FastAPI而非Django或Flask?
Python是AI领域的绝对主流,所以后端语言锁定Python。在Python的Web框架中,Django大而全,但略显笨重,适合从零开始构建复杂的管理系统;Flask轻量灵活,但很多功能需要自己组装,对新手来说选择成本高。FastAPI正好处在中间甜蜜点。
FastAPI的核心优势:
- 性能卓越:基于Starlette(用于异步)和Pydantic(用于数据验证),性能堪比NodeJS和Go,远超传统的同步框架。对于需要频繁调用AI模型(可能涉及I/O等待)的场景,异步支持是天生的优势。
- 开发效率极高:自动生成交互式API文档(Swagger UI和ReDoc),你定义好Pydantic模型和路径操作函数,文档就自动生成了。这对于前后端协作来说,能省去大量手动编写和维护API文档的时间。
- 类型提示与编辑器友好:深度集成Python类型提示,配合Pydantic,能在代码编写阶段就捕获很多数据错误,并且获得极佳的代码补全体验。这大大降低了调试成本。
- 学习曲线平缓:如果你有基本的Python基础,FastAPI的入门非常快。它的设计直观,没有Django那样庞杂的概念体系。
第一周的后端定位:我们不会一上来就搞复杂的ORM(对象关系映射)或者缓存。第一周的后端,核心是提供纯净、高效的API接口。它的职责是接收前端请求,处理业务逻辑(初期可能只是简单的计算或字符串处理),调用AI服务(后续),然后返回结构化的数据(通常是JSON)。FastAPI的轻量和高效,让我们可以专注于API设计本身,而不被框架的繁文缛节所困扰。
2.2 前端:为什么是Vue而非React?
前端选择Vue 3,同样是基于生态、上手难度和与后端配合的考虑。
Vue 3的优势:
- 渐进式与易上手:Vue的核心库只关注视图层,易于与其他库或已有项目整合。其模板语法对于有HTML/CSS/JS基础的人来说非常直观,学习曲线比React的JSX要平缓一些,更适合全栈开发者快速上手前端。
- 组合式API(Composition API):这是Vue 3的亮点。它提供了更好的逻辑复用和代码组织方式,尤其是在处理复杂的、与状态相关的业务逻辑时(比如管理AI模型的调用状态、前后端数据流),比Vue 2的选项式API更灵活、更清晰。
- 丰富的生态系统:Vue Router用于路由管理,Pinia用于状态管理(比Vuex更简单),Element Plus或Ant Design Vue等UI组件库能极大提升开发效率。这些工具都能很好地与FastAPI后端配合。
- 工具链完善:Vite作为构建工具,提供了闪电般的冷启动和热更新,开发体验极佳。
第一周的前端定位:创建一个极简的管理框架或演示页面。这个页面不需要花哨的样式,核心是能通过Axios等HTTP库,成功调用后端的API,并将返回的数据展示出来。这验证了前后端通信的链路是通的。我们可以用一个简单的按钮和一段文本来演示这个过程。
2.3 整体架构:前后端分离
我们采用彻底的前后端分离架构。这意味着:
- 后端(FastAPI):运行在
http://localhost:8000,只提供JSON格式的RESTful API或GraphQL接口。它不负责渲染任何HTML页面(除了自动生成的API文档)。 - 前端(Vue):运行在
http://localhost:5173(Vite默认端口),通过HTTP请求获取后端数据,并在浏览器中渲染页面。 - 通信:前端通过Fetch API或Axios库发送HTTP请求到后端接口。
这样做的好处:
- 职责清晰:后端专注数据和业务逻辑,前端专注交互和展示。
- 独立开发与部署:前后端可以并行开发,只要约定好API接口(这正是FastAPI自动文档的价值)。部署时也可以分开,前端可以部署到CDN,后端部署到云服务器。
- 技术栈灵活:未来如果需要开发移动端App(React Native/Flutter),它们可以直接复用同一套后端API。
第一周的架构目标:就是让这两个独立运行的服务成功“握手”。这涉及到跨域(CORS)问题的解决,这是第一个需要攻克的小技术点。
3. 开发环境配置与项目初始化
工欲善其事,必先利其器。一个稳定、高效的开发环境能避免很多莫名其妙的问题。下面是我推荐的“第一周”环境配置清单和初始化步骤,这些都是我趟过坑后总结出来的稳定方案。
3.1 基础软件安装清单
- Python (>=3.8):去Python官网下载安装包。务必在安装时勾选“Add Python to PATH”。安装后,在终端输入
python --version和pip --version验证。 - Node.js (>=18.x LTS):去Node.js官网下载LTS版本。它自带了npm包管理器。安装后,用
node --version和npm --version验证。 - 代码编辑器/IDE:强烈推荐VS Code。它轻量、免费,并且通过插件对Python、Vue、FastAPI的支持近乎完美。必装插件:
- Python (Microsoft)
- Pylance (Microsoft, 提供更好的类型提示)
- Vue Language Features (Volar) (Vue官方推荐,替代Vetur)
- Auto Close Tag, Auto Rename Tag (HTML/XML标签自动补全)
- Thunder Client 或 REST Client (用于测试API,比Postman更轻量)
- Git:版本控制是必备技能。去Git官网下载安装,并在终端用
git --version验证。建议再配置一下SSH Key连接到GitHub或Gitee。
注意:尽量避免使用系统自带的Python或通过某些第三方软件管理工具安装的版本,可能会遇到路径和权限问题。直接使用官方安装包最稳妥。
3.2 后端项目初始化
我们不把前后端代码混在一个仓库里,而是创建两个独立的项目文件夹,便于管理。
步骤一:创建项目目录并初始化虚拟环境
# 创建一个总项目目录 mkdir ai-fullstack-week1 cd ai-fullstack-week1 # 创建后端目录 mkdir backend cd backend # 创建Python虚拟环境(隔离项目依赖) python -m venv venv # 激活虚拟环境 # Windows: venv\Scripts\activate # macOS/Linux: source venv/bin/activate激活后,终端提示符前会出现(venv)字样。
步骤二:安装核心依赖在激活的虚拟环境下,运行:
pip install fastapi uvicorn[standard] pydantic-settingsfastapi: 核心框架。uvicorn[standard]: ASGI服务器,用于运行FastAPI应用。[standard]包含一些高性能的额外依赖。pydantic-settings: 用于管理配置(如数据库连接字符串、API密钥),比直接写死在代码里更优雅安全。
步骤三:创建第一个FastAPI应用在backend目录下,创建main.py文件:
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware # 创建FastAPI应用实例 app = FastAPI(title="AI FullStack API", version="0.1.0") # 配置CORS(跨域资源共享)中间件 # 这是让前端能访问后端的关键! app.add_middleware( CORSMiddleware, allow_origins=["http://localhost:5173"], # 允许Vue前端开发服务器的地址 allow_credentials=True, allow_methods=["*"], # 允许所有HTTP方法 allow_headers=["*"], # 允许所有HTTP头 ) # 定义一个根路径的GET接口,作为“心跳”检测 @app.get("/") async def root(): return {"message": "Hello from FastAPI Backend!", "status": "alive"} # 定义一个简单的API接口,模拟未来AI处理 @app.get("/api/process") async def process_text(text: str = "Hello AI"): # 这里暂时模拟AI处理,后续会替换成真正的模型调用 processed_text = f"[Processed]: {text.upper()}" return {"original": text, "processed": processed_text, "model_used": "simulator_v1"}步骤四:运行后端服务器在backend目录下,运行:
uvicorn main:app --reload --host 0.0.0.0 --port 8000main:app:main是文件名(不含.py),app是代码中FastAPI()的实例名。--reload:开启热重载,代码修改后自动重启服务器。仅用于开发环境。--host 0.0.0.0:允许从网络其他设备访问(比如同一局域网内的手机测试)。--port 8000:指定端口。
打开浏览器,访问http://localhost:8000,你会看到JSON响应{"message":"Hello from FastAPI Backend!","status":"alive"}。访问http://localhost:8000/docs,你会看到自动生成的Swagger UI交互式API文档,可以在这里直接测试/api/process接口。这非常酷!
3.3 前端项目初始化
步骤一:创建Vue项目打开一个新的终端窗口(确保在ai-fullstack-week1目录下,或者任何你喜欢的目录),使用Vue官方工具创建项目:
# 回到项目根目录,或你想要的目录 cd /path/to/ai-fullstack-week1 # 使用Vite创建Vue项目,项目名设为 `frontend` npm create vue@latest frontend在创建过程中,命令行会交互式地询问你配置选项。对于第一周,我建议如下选择:
Add TypeScript?->No(初期可选,但为了简化先不用)Add JSX Support?->NoAdd Vue Router for Single Page Application?->Yes(路由很重要,迟早要用)Add Pinia for state management?->Yes(状态管理,推荐)Add Vitest for Unit Testing?->No(第一周先跳过测试)Add an End-to-End Testing Solution?->NoAdd ESLint for code quality?->Yes(代码规范,建议)Add Prettier for code formatting?->Yes(代码格式化,建议)
创建完成后,进入项目并安装依赖:
cd frontend npm install步骤二:安装Axios并清理默认页面Axios是一个基于Promise的HTTP客户端,比原生Fetch更好用。
npm install axios然后,我们简化src/App.vue文件,让它专注于测试与后端的连接:
<template> <div class="app"> <header> <h1>AI全栈应用 - 第一周</h1> <p>前端Vue 3 + 后端FastAPI连接测试</p> </header> <main> <div class="card"> <h2>后端状态检查</h2> <button @click="checkBackend">点击检查后端心跳</button> <p v-if="backendStatus">后端响应: {{ backendStatus }}</p> <p v-else class="placeholder">等待检查...</p> </div> <div class="card"> <h2>模拟AI处理</h2> <input v-model="inputText" placeholder="输入一些文字..." /> <button @click="processWithAI" :disabled="isProcessing"> {{ isProcessing ? '处理中...' : '开始处理' }} </button> <div v-if="processedResult"> <h3>处理结果:</h3> <p><strong>原始文本:</strong> {{ processedResult.original }}</p> <p><strong>处理后:</strong> {{ processedResult.processed }}</p> <p><strong>模拟模型:</strong> {{ processedResult.model_used }}</p> </div> </div> </main> </div> </template> <script setup> import { ref } from 'vue' import axios from 'axios' // 配置axios实例,统一设置基础URL,方便后续调用 const apiClient = axios.create({ baseURL: 'http://localhost:8000', // 指向你的FastAPI后端 timeout: 5000 // 5秒超时 }) const backendStatus = ref('') const inputText = ref('你好,世界!') const processedResult = ref(null) const isProcessing = ref(false) const checkBackend = async () => { try { const response = await apiClient.get('/') backendStatus.value = `✅ 连接成功!状态:${response.data.status},消息:${response.data.message}` } catch (error) { backendStatus.value = `❌ 连接失败:${error.message}` console.error('后端连接错误:', error) } } const processWithAI = async () => { if (!inputText.value.trim()) { alert('请输入一些文字') return } isProcessing.value = true processedResult.value = null try { // 调用我们定义的 /api/process 接口 const response = await apiClient.get('/api/process', { params: { text: inputText.value } }) processedResult.value = response.data } catch (error) { console.error('AI处理请求失败:', error) alert('处理请求失败,请检查控制台和后端日志。') } finally { isProcessing.value = false } } </script> <style scoped> /* 简单的样式,只为让页面看起来清晰 */ .app { font-family: sans-serif; max-width: 800px; margin: 0 auto; padding: 2rem; } header { text-align: center; margin-bottom: 3rem; } .card { border: 1px solid #ddd; border-radius: 8px; padding: 1.5rem; margin-bottom: 2rem; background: #f9f9f9; } button { background-color: #42b983; color: white; border: none; padding: 0.75rem 1.5rem; border-radius: 4px; cursor: pointer; font-size: 1rem; margin-right: 1rem; margin-top: 0.5rem; } button:hover { background-color: #33a06f; } button:disabled { background-color: #ccc; cursor: not-allowed; } input { padding: 0.75rem; border: 1px solid #ccc; border-radius: 4px; width: 100%; box-sizing: border-box; font-size: 1rem; margin-top: 0.5rem; } .placeholder { color: #888; font-style: italic; } </style>步骤三:运行前端开发服务器在frontend目录下,运行:
npm run devVite会启动开发服务器,通常运行在http://localhost:5173。打开这个地址,你应该能看到一个简单的页面。点击“点击检查后端心跳”按钮,如果一切配置正确,你会看到来自FastAPI后端的成功响应。然后在输入框里输入文字,点击“开始处理”,前端会调用/api/process接口,并将处理后的结果(目前是大写转换)展示出来。
至此,一个最基础但完整的前后端分离AI应用骨架就搭建成功了。前端可以独立开发,后端提供数据接口,两者通过HTTP协议通信。
4. 核心环节详解:CORS、API设计与状态管理
第一周的项目虽然代码量不大,但涉及的几个核心概念必须理解透彻,否则后续扩展会举步维艰。
4.1 深入理解并配置CORS
跨域问题是你一定会遇到的第一个拦路虎。当你的前端(localhost:5173)试图访问后端(localhost:8000)时,由于端口不同,浏览器出于安全考虑会阻止这种请求。这就是CORS(跨源资源共享)策略。
FastAPI中的CORS配置详解: 我们在main.py中使用的CORSMiddleware是解决此问题的标准方式。关键参数解释:
allow_origins: 一个列表,指定允许跨域请求的源(前端地址)。在生产环境中,这里必须替换成你前端实际部署的域名,如["https://yourdomain.com"],绝对不能是["*"],否则会带来严重的安全风险。allow_credentials: 是否允许携带Cookie等凭证信息。如果前端请求需要认证(如JWT Token),这个通常要设为True。allow_methods: 允许的HTTP方法,如["GET", "POST"]。["*"]表示允许所有方法。allow_headers: 允许的HTTP头。["*"]通常用于开发,生产环境建议明确列出需要的头,如["Authorization", "Content-Type"]。
开发环境下的调试技巧: 如果CORS配置后仍然报错,打开浏览器的开发者工具(F12)的“网络(Network)”标签页,查看失败的请求。检查响应头中是否包含Access-Control-Allow-Origin: http://localhost:5173。如果没有,说明后端CORS中间件没有生效,检查代码和服务器是否已重启。
4.2 设计清晰的前后端API契约
前后端分离的核心是“契约”,即API接口的约定。第一周我们只用了简单的GET请求,但良好的设计习惯要从一开始养成。
FastAPI后端设计要点:
- 使用Pydantic模型定义请求/响应体:这能自动进行数据验证和序列化,并直接体现在API文档中。例如,未来我们有一个POST接口用于提交AI任务:
from pydantic import BaseModel class AIProcessRequest(BaseModel): text: str model_type: str = "default" # 默认值 options: dict = {} # 可选参数 class AIProcessResponse(BaseModel): task_id: str status: str result: str | None = None # 结果可能为空 error: str | None = None @app.post("/api/v1/process", response_model=AIProcessResponse) async def create_ai_task(request: AIProcessRequest): # 业务逻辑... return AIProcessResponse(task_id="123", status="processing") - 合理的API路径规划:建议使用版本前缀,如
/api/v1/,为后续不兼容的API升级留有余地。资源使用复数名词,如/api/v1/tasks,/api/v1/users。 - 统一的响应格式:即使是错误,也返回结构化的JSON,而不是纯文本错误。可以创建一个通用的响应模型。
前端调用规范:
- 封装HTTP客户端:我们已经在
App.vue里用axios.create创建了一个实例,并设置了baseURL。更好的做法是将其提取到一个单独的文件(如src/api/client.js)中,并统一添加请求/响应拦截器,用于处理Token、错误等。 - 错误处理:使用
try...catch包裹所有异步请求,并在界面上给用户友好的提示,而不是在控制台抛出一堆红字。 - 加载状态管理:使用
isProcessing这样的变量来防止用户重复提交,并给出加载中的视觉反馈(如按钮禁用、显示加载动画)。
4.3 前端状态管理初探:Pinia的使用
当应用稍微复杂一点,比如多个组件都需要知道用户是否已登录、或者共享AI处理的结果时,就需要状态管理。Vue 3推荐使用Pinia,它比Vuex更简单直观。
在第一周引入Pinia的意义:即使当前只有一个组件,提前建立状态管理的模式也是好习惯。我们可以把与后端API交互的逻辑(状态)从组件中抽离出来,让组件更专注于视图渲染。
快速设置一个Store:
- 在
src/stores目录下(Vue项目创建时已生成),创建ai.js:import { defineStore } from 'pinia' import { ref } from 'vue' import { apiClient } from '@/api/client' // 假设我们把axios封装在这里 export const useAIStore = defineStore('ai', () => { // 状态 const processingStatus = ref('idle') // 'idle', 'processing', 'success', 'error' const processResult = ref(null) const errorMessage = ref('') // 操作(Actions) async function processText(text) { processingStatus.value = 'processing' errorMessage.value = '' try { const response = await apiClient.get('/api/process', { params: { text } }) processResult.value = response.data processingStatus.value = 'success' } catch (error) { errorMessage.value = `处理失败: ${error.message}` processingStatus.value = 'error' console.error(error) } } // 重置状态 function reset() { processingStatus.value = 'idle' processResult.value = null errorMessage.value = '' } return { processingStatus, processResult, errorMessage, processText, reset } }) - 在
App.vue中使用这个Store:<script setup> import { useAIStore } from '@/stores/ai' import { storeToRefs } from 'pinia' const aiStore = useAIStore() // 使用 storeToRefs 解构保持响应性 const { processingStatus, processResult } = storeToRefs(aiStore) const inputText = ref('') const handleProcess = () => { aiStore.processText(inputText.value) } </script> <template> <!-- 在模板中直接使用 processingStatus.value 和 processResult.value --> <button @click="handleProcess" :disabled="processingStatus.value === 'processing'"> {{ processingStatus.value === 'processing' ? '处理中...' : '开始处理' }} </button> <div v-if="processResult.value"> <!-- 显示结果 --> </div> </template>
这样做的好处是,所有与AI处理相关的状态和逻辑都集中在了Store里,组件变得非常干净。未来如果其他页面也需要显示处理结果,直接引入这个Store即可,数据是共享的。
5. 项目结构优化与后续开发准备
第一周结束时,我们的代码可能都堆在几个文件里。为了项目的长期健康,我们需要规划一个清晰的项目结构。
5.1 后端项目结构建议
backend/ ├── app/ │ ├── __init__.py │ ├── main.py # FastAPI应用创建和中间件配置 │ ├── api/ # 存放所有路由端点 │ │ ├── __init__.py │ │ ├── v1/ # API版本v1 │ │ │ ├── __init__.py │ │ │ ├── endpoints/ # 按功能划分的端点文件,如 auth.py, process.py │ │ │ └── models.py # Pydantic请求/响应模型 │ ├── core/ # 核心配置、安全、依赖项 │ │ ├── config.py # 从环境变量读取配置(用pydantic-settings) │ │ └── security.py # 认证授权相关 │ ├── services/ # 业务逻辑层,如调用AI模型的服务 │ │ └── ai_service.py │ └── utils/ # 工具函数 ├── tests/ # 测试文件 ├── requirements.txt # 生产环境依赖 ├── requirements-dev.txt # 开发环境额外依赖(如测试库、代码格式化工具) └── .env.example # 环境变量示例文件你可以逐步将main.py中的路由移到app/api/v1/endpoints/下的各个文件中,并使用APIRouter进行组织。main.py只负责“组装”应用。
5.2 前端项目结构建议(Vue 3 + Vite)
frontend/ ├── src/ │ ├── api/ # 所有API请求封装 │ │ └── client.js # axios实例和拦截器 │ ├── assets/ # 静态资源 │ ├── components/ # 可复用组件 │ ├── composables/ # 组合式函数(Vue 3特有) │ ├── router/ # Vue Router配置 │ ├── stores/ # Pinia状态管理 │ │ └── ai.js # AI相关状态 │ ├── views/ # 页面级组件 │ ├── App.vue │ └── main.js ├── .env.development # 开发环境变量(如 VITE_API_BASE_URL=http://localhost:8000) ├── .env.production # 生产环境变量 └── vite.config.js # Vite配置关键一步:在.env.development中设置VITE_API_BASE_URL=http://localhost:8000,然后在src/api/client.js中通过import.meta.env.VITE_API_BASE_URL读取这个变量。这样,切换开发/生产环境时,只需修改环境变量文件,无需改动代码。
5.3 版本控制与协作基础
在项目根目录(ai-fullstack-week1)初始化Git仓库可能不是最佳实践,因为前后端通常独立部署。更常见的做法是两个独立的Git仓库:一个给backend,一个给frontend。或者使用Monorepo工具(如 pnpm workspace)管理。对于初学者,我建议先建两个独立仓库,理解更清晰。
必须添加到.gitignore的文件:
- 后端:
venv/,__pycache__/,*.pyc,.env(包含密码和密钥的文件!) - 前端:
node_modules/,dist/,.env.local
重要提示:永远不要将包含敏感信息(如数据库密码、API密钥)的
.env文件提交到Git。应该提交一个.env.example文件,列出需要的环境变量名但不包含真实值。
6. 常见问题与排查技巧实录
在第一周的搭建过程中,你几乎一定会遇到下面这些问题。我把它们和解决方法记录下来,希望能帮你快速排雷。
6.1 后端服务启动失败
问题现象:运行uvicorn main:app --reload时报错,如ModuleNotFoundError: No module named 'fastapi'。
- 原因与解决:虚拟环境未激活或依赖未安装。确保终端提示符前有
(venv),并在该环境下重新执行pip install -r requirements.txt(如果你有requirements文件)或手动安装。
问题现象:Address already in use。
- 原因与解决:端口8000被其他程序占用。可以换一个端口,如
--port 8001,或者找到占用端口的进程并关闭它(在Linux/macOS上用lsof -i:8000,在Windows上用netstat -ano | findstr :8000)。
6.2 前端无法连接后端(CORS错误)
问题现象:浏览器控制台报错Access to fetch at 'http://localhost:8000/' from origin 'http://localhost:5173' has been blocked by CORS policy。
- 排查步骤:
- 检查后端CORS配置:确认
allow_origins里包含了前端地址http://localhost:5173。 - 检查后端是否在运行:直接访问
http://localhost:8000或http://localhost:8000/docs,看是否有响应。 - 检查网络请求:在浏览器开发者工具的“网络”标签中,查看请求是否成功发出,响应头是否包含
Access-Control-Allow-Origin。 - 重启后端服务:修改CORS配置后,需要重启uvicorn才能生效。
- 检查后端CORS配置:确认
6.3 前端npm install 失败或运行缓慢
问题现象:安装依赖时卡住或报网络错误。
- 解决:
- 换源:将npm仓库切换到国内镜像,如淘宝源。
npm config set registry https://registry.npmmirror.com- 清理缓存:
npm cache clean --force - 删除重试:删除
node_modules文件夹和package-lock.json文件,重新运行npm install。
6.4 代码修改后页面无变化
问题现象:修改了Vue组件或FastAPI代码,但浏览器没有刷新或更新。
- 解决:
- 前端:Vite的热重载通常很灵敏。如果没有,尝试手动刷新页面,或检查终端是否有编译错误。
- 后端:确保启动uvicorn时使用了
--reload参数。如果修改了导入的模块(如新建了文件),可能需要重启服务,因为--reload对某些情况不敏感。
6.5 环境变量不生效
问题现象:前端读取import.meta.env.VITE_API_BASE_URL得到undefined。
- 排查:
- 确认环境变量文件命名正确(如
.env.development),且放在项目根目录。 - 确认变量名以
VITE_开头,这是Vite的约定。 - 重启前端开发服务器:环境变量只在服务器启动时被加载。
- 确认环境变量文件命名正确(如
6.6 一个实用的调试技巧:前后端联调
当接口调用出现问题时,不要只在前端猜。
- 首先,用API测试工具直接测后端:打开
http://localhost:8000/docs,在Swagger UI里直接尝试调用你的接口,确认后端本身是否工作正常、返回数据是否符合预期。 - 然后,查看浏览器网络请求:在前端操作,在开发者工具的“网络”标签里查看发出的请求,检查请求的URL、方法、参数(Payload/Query String)是否正确。
- 最后,查看后端日志:uvicorn终端会打印出接收到的每一个请求信息,包括路径、状态码。这是排查问题的金矿。
第一周的核心目标已经达成:你拥有了一个可以独立运行、并能相互通信的前端和后端应用。这个骨架虽然简单,但它遵循了现代Web开发的最佳实践。接下来几周,你可以在这个骨架上添加血肉:集成真正的AI模型(比如通过调用OpenAI API或运行本地机器学习库)、设计数据库、实现用户登录、构建更复杂的UI界面。记住,好的开始是成功的一半,扎实的基础架构会让后续的每一步都走得更稳。