1. 配置环境、创建导航栏
配置环境、创建项目与导航栏
一、目标
完成项目从 0 到 1 的搭建:
- 配置 Python、Node.js、Git、IDE 等开发环境;
- 创建 Django 后端项目与 Vue 3 前端项目;
- 配置 DRF、JWT、CORS、静态文件和媒体文件;
- 使用 Tailwind CSS + DaisyUI 搭建基础导航栏;
- 理解开发环境与生产部署环境的区别;
- 完成前端打包到 Django 后端的基础整合。
本节是整个 AgentTalk 项目的地基,后续登录、角色、聊天、语音模块都建立在这里的前后端工程结构之上。
二、开发环境配置
2.1 Python 与虚拟环境
后端使用 Django,因此需要安装 Python,并建议使用虚拟环境隔离依赖。
python-mvenv .venv .venv\Scripts\activateLinux / macOS:
python-mvenv .venvsource.venv/bin/activate虚拟环境的作用:
- 每个项目拥有独立依赖;
- 避免全局 Python 包版本冲突;
- 方便通过
requirements.txt复现环境。
2.2 Node.js 与 npm
前端使用 Vue 3 + Vite,需要 Node.js 提供构建工具运行环境。
安装地址:https://nodejs.org/
安装时建议勾选Add to PATH。
更新 npm:
npminstall-gnpm@latestNode.js 在本项目中的作用:
- 运行 Vite 开发服务器;
- 管理 Vue、Pinia、DaisyUI 等前端依赖;
- 执行
npm run build,将 Vue 源码打包成浏览器可运行的静态文件。
2.3 Git 与 SSH
安装 Git:https://gitforwindows.org/
生成 SSH Key:
ssh-keygen常用 Git 命令:
gitstatusgitadd.gitcommit-m"提交说明"gitpushgitpullgitclone<repo-url>重点理解
git status:查看工作区与暂存区状态;git add:将修改加入暂存区;git commit:生成本地提交记录;git push:推送到远程仓库;.gitignore:忽略不应该提交的文件,如虚拟环境、数据库、环境变量、打包产物。
2.4 PyCharm / IDE 配置
如果使用 PyCharm:
- 安装中文插件:
Settings -> Plugins -> Marketplace; - 开启 Django 支持:
Settings -> Languages & Frameworks -> Django; - 配置 Django project root、settings、manage.py;
- 将
backend目录标记为 Sources Root,避免无法识别web模块。
三、创建 Django 后端
3.1 创建项目与应用
django-admin startproject backendcdbackend django-admin startapp web python manage.py migrate python manage.py createsuperuser python manage.py runserver目录含义:
backend/ ├── backend/ # Django 项目配置包 │ ├── settings.py # 全局配置 │ ├── urls.py # 根路由 │ ├── wsgi.py # WSGI 部署入口 │ └── asgi.py # ASGI 部署入口 ├── web/ # 业务应用 │ ├── models.py # 默认模型文件,后续可拆成 models/ 目录 │ ├── views.py # 默认视图文件,后续可拆成 views/ 目录 │ └── urls.py # web 应用子路由,需自行创建 └── manage.py # Django 管理脚本3.2 安装后端依赖
pipinstalldjango pipinstalldjangorestframework pipinstalldjangorestframework-simplejwt pipinstalldjango-cors-headers pipinstallpillow依赖说明:
| 包 | 作用 |
|---|---|
django | 后端 Web 框架 |
djangorestframework | 编写 REST API |
djangorestframework-simplejwt | JWT 登录认证 |
django-cors-headers | 处理跨域 |
pillow | 处理图片上传字段 |
四、配置 Django settings.py
4.1 注册应用
INSTALLED_APPS=['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','rest_framework','corsheaders','web',]4.2 跨域中间件
MIDDLEWARE=['corsheaders.middleware.CorsMiddleware','django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',]CorsMiddleware应尽量放在靠前位置。
4.3 时区
TIME_ZONE='Asia/Shanghai'USE_TZ=True4.4 静态文件与媒体文件
STATIC_URL='static/'STATICFILES_DIRS=[BASE_DIR/'static',]MEDIA_URL='/media/'MEDIA_ROOT=BASE_DIR/'media'static 与 media 区别
| 类型 | 含义 | 示例 |
|---|---|---|
static | 开发者提供的静态资源 | JS、CSS、前端打包文件 |
media | 用户上传的动态文件 | 头像、角色背景图 |
4.5 JWT 配置
fromdatetimeimporttimedelta REST_FRAMEWORK={'DEFAULT_AUTHENTICATION_CLASSES':('rest_framework_simplejwt.authentication.JWTAuthentication',),}SIMPLE_JWT={'ACCESS_TOKEN_LIFETIME':timedelta(hours=2),'REFRESH_TOKEN_LIFETIME':timedelta(days=7),'ROTATE_REFRESH_TOKENS':True,'BLACKLIST_AFTER_ROTATION':True,'AUTH_HEADER_TYPES':('Bearer',),}4.6 CORS 配置
CORS_ALLOW_CREDENTIALS=TrueCORS_ALLOWED_ORIGINS=['http://localhost:5173','http://127.0.0.1:5173',]CORS_ALLOW_CREDENTIALS = True用于允许跨域请求携带 Cookie。
五、配置后端路由与前端入口
5.1 项目根路由
backend/backend/urls.py:
fromdjango.contribimportadminfromdjango.urlsimportpath,includefromdjango.confimportsettingsfromdjango.conf.urls.staticimportstatic urlpatterns=[path('admin/',admin.site.urls),path('',include('web.urls')),]ifsettings.DEBUG:urlpatterns+=static('/media/',document_root=settings.MEDIA_ROOT)5.2 web 子路由
backend/web/urls.py:
fromdjango.urlsimportpath,re_pathfromweb.views.indeximportindex urlpatterns=[path('',index),re_path(r'^(?!media/|static/|assets/).*$',index),]5.3 前端 History 模式刷新问题
Vue Router 使用createWebHistory()时,浏览器访问/friend、/create等路径会先请求后端。
如果后端没有对应路由,会出现 404。因此需要:
re_path(r'^(?!media/|static/|assets/).*$',index)含义:
- 排除媒体和静态资源路径;
- 其他路径都返回同一个
index.html; - 真正的页面匹配交给 Vue Router 完成。
六、创建 Vue 3 前端
6.1 创建项目
npmcreate vue@latestcdfrontendnpminstall推荐选择:
- Vue Router;
- Pinia;
- ESLint / Prettier 可按需要选择。
6.2 安装 Tailwind CSS 与 DaisyUI
npminstall-Dtailwindcss @tailwindcss/vitenpminstall-Ddaisyui在frontend/src/assets/main.css中:
@import"tailwindcss";@plugin"daisyui";6.3 配置 Vite 打包输出
frontend/vite.config.js:
import{fileURLToPath,URL}from'node:url'import{defineConfig}from'vite'importvuefrom'@vitejs/plugin-vue'importtailwindcssfrom'@tailwindcss/vite'importpathfrom'path'exportdefaultdefineConfig({plugins:[vue(),tailwindcss()],build:{outDir:path.resolve(__dirname,'../backend/static/frontend'),emptyOutDir:true,},resolve:{alias:{'@':fileURLToPath(newURL('./src',import.meta.url)),},},})这样执行:
npmrun build前端产物会输出到 Django 的backend/static/frontend。
七、前端基础结构
frontend/src/ ├── App.vue # 根组件 ├── main.js # 入口文件 ├── router/index.js # 路由配置 ├── stores/ # Pinia 状态 ├── components/ # 公共组件 │ └── navbar/ # 导航栏组件 └── views/ # 页面组件 ├── homepage/ ├── friend/ ├── create/ ├── user/account/ ├── user/profile/ └── error/7.1 App.vue
<script setup> import NavBar from '@/components/navbar/NavBar.vue' </script> <template> <NavBar> <RouterView /> </NavBar> </template>RouterView是页面出口,当前路由匹配到的组件会渲染在这里。
八、Vue Router 路由配置
import{createRouter,createWebHistory}from'vue-router'importHomepageIndexfrom'@/views/homepage/HomepageIndex.vue'importFriendIndexfrom'@/views/friend/FriendIndex.vue'importCreateIndexfrom'@/views/create/CreateIndex.vue'importLoginIndexfrom'@/views/user/account/LoginIndex.vue'importRegisterIndexfrom'@/views/user/account/RegisterIndex.vue'importProfileIndexfrom'@/views/user/profile/ProfileIndex.vue'importNotFoundIndexfrom'@/views/error/NotFoundIndex.vue'constrouter=createRouter({history:createWebHistory(import.meta.env.BASE_URL),routes:[{path:'/',component:HomepageIndex,name:'homepage-index'},{path:'/friend',component:FriendIndex,name:'friend-index'},{path:'/create',component:CreateIndex,name:'create-index'},{path:'/login',component:LoginIndex,name:'login-index'},{path:'/register',component:RegisterIndex,name:'register-index'},{path:'/user/profile',component:ProfileIndex,name:'user-profile-index'},{path:'/:pathMatch(.*)*',component:NotFoundIndex,name:'not-found'},],})exportdefaultrouter8.1 404 路由易错点
正确写法:
{path:'/:pathMatch(.*)*',component:NotFoundIndex}错误写法:
{path:'/:pathMatch(*)*',component:NotFoundIndex}错误原因:(*)不是合法正则,会导致路由文件解析失败,前端白屏。
九、导航栏组件设计
9.1 导航栏功能
导航栏包含:
- 左侧菜单按钮;
- 项目标题;
- 搜索框;
- 登录 / 注册 / 用户头像菜单;
- 侧边栏路由入口:首页、好友、创作。
9.2 RouterLink
RouterLink用于前端无刷新跳转:
<RouterLink :to="{ name: 'homepage-index' }" active-class="menu-focus"> 首页 </RouterLink>重点:
to指定跳转目标;name必须和路由表中一致;active-class用于当前页面高亮。
9.3 Tailwind / DaisyUI 常用类
| 类 | 含义 |
|---|---|
flex | 弹性布局 |
justify-center | 主轴居中 |
items-center | 交叉轴居中 |
w-60 | 宽度,Tailwind 中 1 单位通常为 0.25rem |
px-2 | x 方向内边距 |
mx-2 | x 方向外边距 |
btn | DaisyUI 按钮 |
navbar | DaisyUI 导航栏 |
drawer | DaisyUI 抽屉侧边栏 |
十、前后端整合流程
10.1 开发环境
开发时通常启动两个服务:
# 后端cdbackend python manage.py runserver# 前端cdfrontendnpmrun dev访问:
- 前端:
http://localhost:5173 - 后端:
http://127.0.0.1:8000
此时前后端通过 CORS 通信。
10.2 生产 / 打包环境
cdfrontendnpmrun build构建后:
- Vue 源码被编译成 JS、CSS、图片等静态资源;
- 静态资源输出到 Django 的
static/frontend; - Django 返回
index.html; - 浏览器加载静态资源并启动 Vue 应用。
10.3 完整访问生命周期
- 用户访问
http://127.0.0.1:8000/; - Django 路由匹配根路径,返回
index.html; - 浏览器解析 HTML,请求 JS / CSS 静态资源;
- Vue 应用启动,接管页面渲染;
- 用户操作页面时,Vue 调用 Django API 获取数据;
- Django 查询数据库或调用大模型服务,返回 JSON / SSE 数据。
十一、Git 忽略文件建议
__pycache__/ *.py[cod] .venv/ .env *.env node_modules/ dist/ .idea/ .vscode/ db.sqlite3 media/ static/frontend/ frontend/public/vad/不要提交:
- API Key;
- 本地数据库;
- 用户上传文件;
- 虚拟环境;
node_modules;- 大体积模型文件。
十二、本节易错点
12.1 项目路径不要包含中文
部分 Python 包或前端工具在中文路径下可能出现编码或路径解析问题。
12.2 CORS 与 Cookie
如果前端需要携带 Cookie:
前端:
axios.create({withCredentials:true,})后端:
CORS_ALLOW_CREDENTIALS=True12.3 static 和 media 不要混淆
- 前端打包产物属于
static; - 用户头像、角色图属于
media。
12.4 前端路由刷新 404
需要 Django 添加兜底:
re_path(r'^(?!media/|static/|assets/).*$',index)12.5 路由名称要统一
RouterLink中的name必须和router/index.js中完全一致,否则点击后无法跳转。
十三、小结
本节完成了项目基础骨架:
- Django 提供后端 API、数据库、静态资源服务;
- Vue 负责 SPA 页面和用户交互;
- Vite 负责开发热更新与生产打包;
- Tailwind CSS + DaisyUI 提供 UI 能力;
- Vue Router 负责前端页面切换;
- Django 的兜底路由解决 History 模式刷新问题。
后续所有模块都围绕这套结构继续扩展:登录模块负责用户身份,角色模块负责内容生产,信息流负责展示,聊天模块负责 AI 交互,语音模块负责自然交互体验。
十四、新手跟做路线
如果你是第一次做这种项目,可以按下面顺序操作,不要一开始就关注所有配置细节。
14.1 第一步:确认后端能跑
进入后端目录:
cdbackend python manage.py runserver看到类似下面内容就说明 Django 启动成功:
Starting development server at http://127.0.0.1:8000/浏览器打开:
http://127.0.0.1:8000/如果能看到页面或前端入口,说明后端服务正常。
14.2 第二步:确认前端能跑
进入前端目录:
cdfrontendnpminstallnpmrun dev浏览器打开:
http://localhost:5173/如果页面可以显示,并且修改 Vue 文件后页面自动刷新,说明 Vite 开发服务器正常。
14.3 第三步:确认前后端能通信
在浏览器按F12打开开发者工具,切换到Network。
刷新页面后观察:
- 是否有请求发往
http://127.0.0.1:8000; - 状态码是否为
200; - 如果是
404,优先检查后端路由; - 如果是 CORS 错误,优先检查
django-cors-headers配置。
十五、新手常见问题排查
15.1 运行 python manage.py runserver 报错
常见原因:
- 没进入
backend目录; - 虚拟环境没激活;
- 依赖没安装;
settings.py配置写错;- 数据库迁移没执行。
排查顺序:
python--versionpip list python manage.py check python manage.py migrate python manage.py runserver15.2 npm run dev 报错
常见原因:
- 没安装 Node.js;
- 没执行
npm install; node_modules缺失;- 端口被占用;
package.json依赖版本冲突。
排查:
node-vnpm-vnpminstallnpmrun dev15.3 页面白屏
检查顺序:
- 浏览器 Console 是否有红色报错;
- 路由配置是否写错;
- 组件导入路径是否大小写一致;
App.vue是否正确包含RouterView;- 后端返回的
index.html是否加载到了 JS 文件。
15.4 访问前端路由刷新 404
例如刷新:
http://127.0.0.1:8000/user/profile/如果后端返回 404,说明 Django 没有把这个路径交给 Vue,需要检查:
re_path(r'^(?!media/|static/|assets/).*$',index)十六、本节复习问题
backend和frontend分别负责什么?static和media有什么区别?- 为什么 Vue Router 的 History 模式刷新时需要 Django 兜底路由?
npm run dev和npm run build有什么区别?- 为什么不能把
.env、node_modules、用户上传文件提交到 Git? RouterLink和普通<a>标签有什么区别?- 为什么项目要使用组件化开发?
十七、核心页面请求 / 响应示例
基础环境这一节还没有复杂业务接口,但有两个非常重要的访问路径。
17.1 访问首页入口
GET /成功响应通常是 HTML:
<divid="app"></div><scripttype="module"src="/src/main.js"></script>它的作用是把浏览器交给 Vue 接管。
17.2 访问静态资源
GET /assets/index.js GET /assets/index.css成功响应:
JavaScript 或 CSS 文件内容如果这里 404,页面通常会白屏。
17.3 访问用户上传资源
GET /media/user/photo/alice.png成功响应:
图片二进制内容浏览器会把它显示成图片。
十八、关键代码逐行解释示例
18.1 Vue 应用入口
import{createApp}from'vue'importAppfrom'./App.vue'importrouterfrom'./router'createApp(App).use(router).mount('#app')逐行解释:
| 代码 | 新手解释 |
|---|---|
import { createApp } from 'vue' | 从 Vue 中导入创建应用的方法 |
import App from './App.vue' | 导入根组件,整个页面从这里开始 |
import router from './router' | 导入前端路由配置 |
createApp(App) | 创建一个 Vue 应用实例 |
.use(router) | 给 Vue 应用安装路由能力 |
.mount('#app') | 把 Vue 应用挂载到 HTML 中 id 为 app 的元素上 |
18.2 Django 兜底路由
re_path(r'^(?!media/|static/|assets/).*$',index)逐段解释:
| 代码 | 新手解释 |
|---|---|
re_path | 使用正则表达式匹配 URL |
^(?!...) | 负向排除,表示不要匹配某些开头 |
media/ | 排除用户上传文件路径 |
static/ | 排除后端静态文件路径 |
assets/ | 排除前端打包资源路径 |
.*$ | 匹配其他所有路径 |
index | 返回前端入口页面,让 Vue Router 接管 |
十九、Vue 组件数据传递图
main.js ↓ 创建 Vue 应用 App.vue ↓ 放置 RouterView router/index.js ↓ 根据 URL 决定显示哪个页面 NavBar.vue ↓ 点击 RouterLink HomePage.vue / FriendPage.vue / ProfilePage.vue导航栏状态变化:
Pinia user store ↓ 提供登录状态 NavBar.vue ├── 未登录:显示登录 / 注册按钮 └── 已登录:显示头像 / 用户菜单二十、后端入口视图处理流程
浏览器访问 / 或 /friend/ 等前端路由 ↓ Django URL 匹配 ↓ 如果是 /media/、/static/、/assets/,返回对应资源 ↓ 如果不是资源路径,进入兜底路由 ↓ index 视图返回 index.html ↓ 浏览器加载 JS 和 CSS ↓ Vue Router 根据当前 URL 渲染对应页面二十一、小练习与自测答案
练习 1
问题:为什么刷新/friend/页面时不能直接让 Django 查找一个后端页面?
答案:/friend/是 Vue Router 的前端路由,不是 Django 业务接口。刷新时 Django 需要返回同一个index.html,再由 Vue 根据 URL 渲染好友页面。
练习 2
问题:为什么兜底路由要排除/media/和/assets/?
答案:这些路径是真实资源路径。如果不排除,浏览器请求图片或 JS 文件时会拿到index.html,导致图片无法显示或页面白屏。
练习 3
问题:为什么导航栏适合做成公共组件?
答案:导航栏在多个页面都会出现。做成组件后,只维护一份代码,所有页面都能复用。
