从零构建带AI流式对话的Vue2全栈应用
🗺️ 总览:你的技术路线图
你可以把整个学习过程看作一次“盖房子”的旅程,每一步都有明确的目标:
打地基 (阶段一 & 二): 掌握
Vue 2+Element UI,能搭建出管理后台的前端页面。通水电 (阶段三): 学会
Axios,让前端页面能与后端API进行数据通信。装门禁 (阶段四 & 五): 攻克
微信OAuth鉴权和Cookie Token持久化,实现安全的用户登录与状态管理。上AI大脑 (阶段六): 掌握
SSE流式AI应答,实现类ChatGPT的“打字机”对话效果。做精装 (阶段七 & 八): 学会
响应式布局和Webpack多环境构建,让应用在手机、电脑上都能完美运行,并适应开发、测试、生产等多种环境。
📅 学习路线图:Vue 2 + 微信 OAuth + SSE AI 流式应答
本路线图面向有一定编程基础的学习者,目标是从零构建一个具备微信登录和AI流式对话能力的Web应用。全篇分为理论基础篇和实战操作篇,建议按顺序执行。
🧠 第一部分:理论基础与知识清单
🟢 阶段一:基石 - Vue 2 单页应用开发
学习目标:理解Vue的核心思想,能独立搭建并开发一个Vue 2单页应用(SPA)。
学习周期:1-2周
📖 核心知识点
Vue 核心:理解渐进式框架和MVVM模式。掌握
data、methods、computed、watch、生命周期钩子(created,mounted等)。模板语法:熟练使用
v-if、v-for、v-bind、v-on、v-model等核心指令。组件化:掌握单文件组件(.vue)的开发模式,理解
props、$emit等组件间通信方式。路由管理:学习Vue Router,实现SPA中的页面切换、路由传参和导航守卫。
状态管理:了解Vuex的核心概念(
state,mutations,actions,getters),知道它用于管理全局共享数据。
✅ 实操任务
使用 Vue CLI 创建一个新的 Vue 2 项目。
在项目中创建并使用你自己的第一个 Vue 组件。
配置 Vue Router,实现“首页”和“关于”两个页面的切换。
在“首页”组件中,使用
v-for渲染一个列表数据,使用v-if控制元素的显示与隐藏。实现一个简单的父子组件通信:父组件通过
props向子组件传递数据,子组件通过$emit向父组件发送消息。(可选)在一个简单的场景中尝试使用 Vuex,例如在多个组件间共享用户登录状态。
🟢 阶段二:UI美化 - Element UI + 响应式布局
学习目标:能使用Element UI组件库快速搭建美观的后台界面,并掌握让页面适配手机和电脑的响应式设计。
学习周期:1周
📖 核心知识点
Element UI 核心组件:熟练使用
el-container(布局容器)、el-menu(导航菜单)、el-table(表格)、el-form(表单)、el-dialog(对话框)等。栅格系统:理解Element UI基于24栏的栅格布局,掌握
el-row和el-col的用法。响应式断点:学习并使用
xs,sm,md,lg,xl属性来实现不同屏幕尺寸下的布局切换。SCSS预处理器:了解SCSS的基本语法(变量、嵌套、混合等),并能够在Vue组件中编写
<style lang="scss">。
✅ 实操任务
在项目中引入Element UI,并实现一个包含左侧菜单和右侧内容区的经典后台布局。
在内容区使用
el-table和el-form搭建一个简单的“用户管理”界面。使用Element UI的栅格系统,尝试搭建一个在不同屏幕下(手机、平板、桌面)显示不同列数的卡片列表。
学习如何在Vue组件中使用SCSS,并定义一个主题色变量,然后在多处引用它。
🟢 阶段三:通信 - Axios REST API 通信
学习目标:掌握使用Axios库与后端RESTful API进行数据交互的方法。
学习周期:3-5天
📖 核心知识点
Axios基础:掌握
axios.get()、axios.post()等方法,发送GET和POST请求。请求与响应拦截器:学习使用拦截器(Interceptors)在请求发送前或响应返回后执行统一逻辑(如添加Token、处理错误)。
错误处理:统一处理请求错误,并在UI上给予用户友好提示。
API封装:将项目中所有的API请求统一封装在
src/api/目录下,提高代码的可维护性。
✅ 实操任务
在项目中安装并配置Axios。
使用
axios.get请求一个公开的API(如天气预报、新闻列表),并将返回的数据渲染到页面上。封装一个
request.js文件,创建Axios实例,并配置好基础URL(baseURL)。在
request.js中添加一个请求拦截器,在控制台打印出每次请求的配置信息。在
src/api/目录下创建一个user.js文件,封装一个“获取用户信息”的API方法。
🔐 阶段四:鉴权 - 微信 OAuth 鉴权
学习目标:理解OAuth 2.0协议在微信网页授权中的完整流程,并能在项目中实现“微信登录”功能。
学习周期:1周
📖 核心知识点
OAuth 2.0 概念:理解资源拥有者(用户)、客户端(你的应用)、授权服务器(微信)等核心角色和交互流程。
微信网页授权流程:重点掌握授权码模式(Authorization Code)。
前端引导用户跳转至微信的授权页面。
用户授权后,微信重定向回你的页面并携带一个
code。前端将
code传递给后端。后端使用
code+appid+secret去微信服务器换取access_token和用户的openid。
前后端协作:明确前端负责引导和获取code,后端负责用code换取用户信息并生成你自己的会话凭证(如JWT)。
✅ 实操任务
在微信公众平台申请一个测试号,获取
appid和secret。学习如何构造微信OAuth的授权URL,并尝试在浏览器中访问,观察跳转和回调过程。
在你的Vue项目中,创建一个“微信登录”按钮,点击后跳转到微信授权页面。
在回调页面,从URL中获取
code参数。编写一个API方法,将获取到的
code发送给你的后端。(可选)如果你有后端开发能力,尝试实现用
code换取openid的接口。
🛡️ 阶段五:安全 - Cookie Token 持久化
学习目标:理解将Token存储在HttpOnly Cookie中的安全优势,并掌握其实现方法。
学习周期:3-5天
📖 核心知识点
存储方式对比:对比
localStorage和Cookie存储Token的差异,理解localStorage容易受到XSS攻击的风险。HttpOnly Cookie:理解设置
HttpOnly标志的Cookie无法被JavaScript读取,从而从根本上防御了XSS窃取Token的风险。安全标志:了解
Secure(仅HTTPS传输)和SameSite(防CSRF攻击)标志的作用。实现方式:明确Token应由后端在登录成功后,通过
Set-Cookie响应头写入,而非前端通过JS写入。
✅ 实操任务
查找资料,理解XSS攻击的原理,以及它如何能窃取
localStorage中的数据。(概念性任务)画一张流程图,对比“Token存在localStorage”和“Token存在HttpOnly Cookie”两种方案的安全性与工作流程。
(需后端配合)与后端同学沟通,将登录接口的返回方式改为:成功时在响应头中
Set-Cookie,且Cookie带有HttpOnly和Secure标志。
⚡ 阶段六:AI交互 - SSE 流式 AI 应答(整条路线最核心)
学习目标:掌握使用SSE技术接收服务器流式数据,并实现“打字机”效果的AI对话界面。这是整条路线中最核心、最有价值的部分。
学习周期:1-2周
📖 核心知识点
SSE 原理:理解SSE是一种基于HTTP的轻量级实时通信技术,允许服务器单向向客户端推送数据。
EventSource API:学习浏览器原生提供的
EventSourceAPI,用于在前端建立SSE连接。接收与渲染消息:掌握通过
onmessage事件接收数据,并增量式地将文本片段追加到对话区域,实现“打字机”效果。生命周期管理:了解如何处理连接建立(
onopen)、接收消息(onmessage)、发生错误(onerror)等事件。
✅ 实操任务
找一个支持SSE的公共API(或自己用Node.js/Python写一个简单的SSE服务器)。
在Vue项目中,使用
new EventSource('/your-sse-endpoint')建立连接。在
onmessage回调中,将接收到的文本片段实时追加到页面的<div>中,模拟AI逐字输出的效果。实现一个“停止生成”的按钮,点击后调用
eventSource.close()关闭连接。(进阶)尝试使用
fetchAPI +ReadableStream来实现SSE,这种方式可以支持POST请求和自定义请求头,更加灵活。
🏗️ 阶段七:工程化 - Webpack 多环境构建
学习目标:理解前端工程化的概念,能够配置Webpack实现开发、测试、生产等多环境的代码构建。
学习周期:1周
📖 核心知识点
环境变量:理解
development、test、production等环境的概念,及其对应的用途。配置文件分离:学习使用
webpack-merge等工具,将公共配置抽离到webpack.base.js,并为不同环境创建专属配置文件(如webpack.dev.js,webpack.prod.js)。环境变量注入:掌握使用
DefinePlugin或在Vue CLI项目中使用.env文件,将环境变量注入到前端代码中。
✅ 实操任务
在你的Vue CLI项目中,创建
.env.development和.env.production两个文件。在两个文件中分别定义
VUE_APP_API_BASE_URL变量,值为不同环境的后端API地址。在Vue组件中,通过
process.env.VUE_APP_API_BASE_URL获取该变量,并输出到控制台。分别执行
npm run build,对比不同环境下构建出的文件有何不同(如API地址是否被替换)。
💻 第二部分:实战操作手册(从零开始敲代码)
🗺️ 第零步:环境与工具准备(1天)
在开始写代码之前,先把“枪”擦好。
| 工具 | 具体版本/操作 | 验证方法 |
|---|---|---|
| Node.js | 下载18.x LTS或20.x LTS版本安装 | 命令行输入node -v,显示v18.x.x |
| 包管理器 | 使用yarn或npm(推荐yarn,速度更快) | npm install -g yarn |
| 代码编辑器 | VS Code(装好Vetur或Volar插件) | 打开.vue文件能高亮显示 |
| 浏览器 | Google Chrome(装好Vue.js devtools插件) | F12 打开控制台,能看到Vue标签 |
| 微信测试号 | 申请一个微信公众平台测试号(不用认证) | 拿到appID和appsecret |
🚀 阶段一实战:从零搭建 Vue 2 项目(2天)
目标:在浏览器里看见你自己的 Vue 项目首页。
第一步:创建项目
打开命令行,进入你的工作目录(比如D:\project),执行:
# 使用 Vue CLI 创建项目(如果没装,先执行 npm install -g @vue/cli) vue create my-ai-web # 手动选择配置(选 Vue 2, Router, Vuex, CSS Pre-processors) # 记住!一定要选 Vue 2 版本,不要选 Vue 3第二步:启动项目
cd my-ai-web yarn serve打开浏览器访问http://localhost:8080,看到 Vue 的欢迎界面,阶段一的前半部分完成。
第三步:写一个自己的组件(加深理解)
在src/components下新建HelloWorld.vue,把默认代码清空,自己写一个最简单的:
<template> <div> <!-- 1. 使用插值表达式显示数据 --> <h1>{{ message }}</h1> <!-- 2. 使用 v-for 循环渲染列表 --> <ul> <li v-for="(item, index) in list" :key="index">{{ item }}</li> </ul> <!-- 3. 使用 v-if 控制显示 --> <p v-if="showTip">这是一行提示文字</p> <!-- 4. 使用 v-model 双向绑定 --> <input v-model="inputValue" placeholder="输入文字" /> <p>你输入的是:{{ inputValue }}</p> </div> </template> <script> export default { data() { return { message: '你好,我正在学习 Vue 2!', list: ['苹果', '香蕉', '橘子'], showTip: true, inputValue: '' } } } </script>然后去App.vue里引入这个组件,看看页面上的变化。
🎨 阶段二实战:引入 Element UI + 响应式布局(3天)
目标:让你的页面从“毛坯房”变成“精装房”。
第一步:安装 Element UI
yarn add element-ui在src/main.js中全局引入:
import Vue from 'vue' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI)第二步:搭建后台经典布局
在src/App.vue中,替换成以下代码,实现“左侧菜单 + 右侧内容”:
<template> <el-container style="height: 100vh;"> <!-- 左侧菜单 --> <el-aside width="200px" style="background-color: #304156;"> <el-menu background-color="#304156" text-color="#fff" active-text-color="#ffd04b"> <el-menu-item index="1">首页</el-menu-item> <el-menu-item index="2">用户管理</el-menu-item> </el-menu> </el-aside> <!-- 右侧内容区 --> <el-container> <el-header style="background-color: #fff; border-bottom: 1px solid #ddd;"> <span>我的AI应用</span> </el-header> <el-main> <!-- 这里放你的页面内容 --> <el-table :data="tableData" style="width: 100%"> <el-table-column prop="date" label="日期"></el-table-column> <el-table-column prop="name" label="姓名"></el-table-column> </el-table> </el-main> </el-container> </el-container> </template> <script> export default { data() { return { tableData: [{ date: '2024-01-01', name: '张三' }] } } } </script>第三步:响应式布局(让手机也能看)
把上面的<el-aside width="200px">改成:
<el-aside :width="isCollapse ? '64px' : '200px'">同时,在<el-menu>上加上:collapse="isCollapse",并在 data 里定义isCollapse: false。
核心响应式知识点:使用 Element UI 的栅格系统。
<el-row :gutter="20"> <el-col :xs="24" :sm="12" :md="8" :lg="6" v-for="item in 4" :key="item"> <div class="grid-content">卡片 {{ item }}</div> </el-col> </el-row>解读:在手机(xs)上占满一整行,在平板(sm)上占一半,在电脑(md)上占三分之一。
📡 阶段三实战:Axios 前后端通信(2天)
目标:让你的前端能向后端“要数据”。
第一步:安装 Axios
yarn add axios第二步:封装 request.js(这是核心)
在src/utils/request.js中写入:
import axios from 'axios' // 创建一个 Axios 实例 const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // 从环境变量读取地址 timeout: 30000 // 超时时间 30 秒 }) // 请求拦截器(在发请求前自动添加 Token) service.interceptors.request.use( config => { // 从 Cookie 中读取 Token(后面学) const token = document.cookie.split('; ').find(row => row.startsWith('token=')) if (token) { config.headers['Authorization'] = 'Bearer ' + token.split('=')[1] } return config }, error => { return Promise.reject(error) } ) // 响应拦截器(统一处理返回数据) service.interceptors.response.use( response => { const res = response.data // 如果返回的 code 不是 200,说明接口报错了 if (res.code !== 200) { console.error('接口报错:', res.message) return Promise.reject(new Error(res.message || 'Error')) } return res }, error => { console.error('网络错误:', error) return Promise.reject(error) } ) export default service第三步:写一个 API
在src/api/user.js中写入:
import request from '@/utils/request' // 获取用户信息 export function getUserInfo() { return request({ url: '/user/info', method: 'get' }) }第四步:在页面中调用
在你之前的 Vue 组件中,加入:
import { getUserInfo } from '@/api/user' export default { methods: { async fetchUser() { try { const res = await getUserInfo() console.log('用户信息:', res.data) } catch (error) { console.error('获取用户失败', error) } } }, mounted() { this.fetchUser() // 页面加载时自动执行 } }🔐 阶段四实战:微信 OAuth 登录(3天)
目标:让用户能通过微信扫码登录你的网页。
第一步:配置微信测试号
登录 微信公众平台测试号,拿到appID和appsecret。
在“网页授权域名”中填写你的本地 IP 地址(不要写localhost,要写192.168.x.x)。
第二步:前端跳转微信授权页
在你页面的“登录”按钮上,绑定这个方法:
handleWechatLogin() { // 你的 appID const appId = 'wx1234567890' // 你的回调地址(需要 URL 编码) const redirectUri = encodeURIComponent('http://你的IP地址:8080/oauth/callback') // 微信官方授权 URL const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect` // 跳转到微信 window.location.href = url }第三步:写一个回调页面
在src/views/OauthCallback.vue中,从 URL 中取出code:
<template> <div>正在登录中,请稍候...</div> </template> <script> import { getQueryParam } from '@/utils/index' export default { mounted() { // 从 URL 中取 code const code = getQueryParam('code') if (code) { // 把 code 发送给后端,换取登录凭证 this.loginWithCode(code) } }, methods: { async loginWithCode(code) { try { const res = await this.$http.post('/auth/wechat/login', { code }) // 登录成功,后端会通过 Set-Cookie 写入 Token this.$router.push('/') } catch (error) { console.error('登录失败', error) } } } } </script>第四步:后端配合(理解原理)
后端需要做两件事:
用
code+appid+secret去微信服务器换取access_token和openid。根据
openid生成你自己的jwt token,并通过响应头Set-Cookie写入浏览器。
🛡️ 阶段五实战:Cookie Token 持久化(1天)
目标:确保用户刷新页面后,登录状态不会丢失。
原理:后端登录成功后,在响应头中加上:
Set-Cookie: token=xxxxx; HttpOnly; Secure; SameSite=Lax; Max-Age=86400加上HttpOnly后,前端 JavaScript 无法读取这个 Cookie,但浏览器在每次请求时会自动带上它。
前端验证方法:
打开浏览器 F12 -> Application -> Cookies,看看有没有token字段。
然后刷新页面,观察 Axios 请求中是否自动带上了Authorization头。
⚡ 阶段六实战:SSE 流式 AI 应答(4天)
这是整条路线最有价值、也是最难的一步!目标:实现“打字机”效果。
第一步:了解什么是 SSE
传统的 API 是一次性返回完整数据。SSE(Server-Sent Events)允许服务器像“广播”一样,一点点地把数据推送给前端。
第二步:前端建立 SSE 连接
在src/views/Chat.vue中:
<template> <div> <!-- 对话显示区 --> <div class="chat-box"> <div v-for="(msg, index) in messages" :key="index"> <span v-if="msg.role === 'user'">我:</span> <span v-else>AI:</span> {{ msg.content }} </div> <!-- 当前正在生成的流式内容 --> <div v-if="streamingContent">AI:{{ streamingContent }}</div> </div> <!-- 输入框 --> <input v-model="question" @keyup.enter="sendQuestion" placeholder="输入你的问题" /> <button @click="sendQuestion">发送</button> <button @click="stopStream">停止生成</button> </div> </template> <script> export default { data() { return { question: '', messages: [], streamingContent: '', eventSource: null } }, methods: { sendQuestion() { if (!this.question) return // 1. 把用户的问题加到对话列表 this.messages.push({ role: 'user', content: this.question }) // 2. 创建 SSE 连接 this.eventSource = new EventSource(`/api/ai/stream?question=${encodeURIComponent(this.question)}`) // 3. 监听服务器发来的消息 this.eventSource.onmessage = (event) => { // 服务器发来一个数据块 const data = JSON.parse(event.data) if (data.type === 'content') { // 追加文字(打字机效果) this.streamingContent += data.text } else if (data.type === 'end') { // 流结束,把完整内容加入对话列表,清空临时变量 this.messages.push({ role: 'ai', content: this.streamingContent }) this.streamingContent = '' this.eventSource.close() } } // 4. 错误处理 this.eventSource.onerror = (error) => { console.error('SSE 连接错误', error) this.eventSource.close() } // 清空输入框 this.question = '' }, stopStream() { if (this.eventSource) { this.eventSource.close() this.streamingContent = '' } } } } </script>第三步:后端需要做什么(概念理解)
后端(无论是 Java、Python 还是 Node.js)需要设置响应头:
Content-Type: text/event-stream Cache-Control: no-cache Connection: keep-alive然后每隔几百毫秒,往前端推送一行数据:
data: {"type":"content","text":"你"} data: {"type":"content","text":"好"} data: {"type":"end"}🏗️ 阶段七实战:Webpack 多环境构建(1天)
目标:开发环境连测试后端,生产环境连正式后端。
第一步:创建环境变量文件
在项目根目录:
.env.development(开发环境):
NODE_ENV=development VUE_APP_BASE_API=http://localhost:8081/api.env.production(生产环境):
NODE_ENV=production VUE_APP_BASE_API=https://api.your-company.com第二步:在代码中使用
你的request.js中的baseURL会自动读取process.env.VUE_APP_BASE_API。
第三步:打包验证
yarn build:prod # 打包生产环境 yarn build:stage # 打包测试环境打包完成后,去dist文件夹里看js文件,搜索https://api,你会发现地址已经被替换成对应的环境地址了。
🎯 项目目录结构(供参考)
my-ai-web/ ├── public/ │ └── index.html ├── src/ │ ├── api/ # 所有 API 接口 │ │ ├── user.js │ │ └── ai.js │ ├── assets/ # 静态资源 │ ├── components/ # 公共组件 │ │ └── HelloWorld.vue │ ├── router/ # 路由配置 │ │ └── index.js │ ├── store/ # Vuex 状态管理 │ │ └── index.js │ ├── utils/ # 工具函数 │ │ └── request.js # Axios 封装 │ ├── views/ # 页面 │ │ ├── Login.vue │ │ ├── Chat.vue # AI 对话页面 │ │ └── OauthCallback.vue # 微信回调页 │ ├── App.vue │ └── main.js ├── .env.development # 开发环境变量 ├── .env.production # 生产环境变量 ├── package.json └── vue.config.js # Webpack 额外配置
📆 最终时间表(按天执行)
| 天数 | 任务 | 产出物 |
|---|---|---|
| Day 1 | 装环境 + 创建 Vue 项目 | 看到默认首页 |
| Day 2-3 | 学 Vue 核心指令 + 写第一个组件 | 能自定义组件 |
| Day 4-5 | 引入 Element UI + 搭建后台布局 | 看到美观的界面 |
| Day 6 | 学习响应式(栅格系统) | 手机、电脑都能看 |
| Day 7-8 | 封装 Axios + 调通第一个接口 | 控制台打印出数据 |
| Day 9-10 | 微信 OAuth 配置 + 跳转测试 | 能跳转到微信授权页 |
| Day 11 | Cookie Token 理解 + 验证 | F12 能看到 Cookie |
| Day 12-14 | SSE 流式对话实现 | 看到“打字机”效果 |
| Day 15 | Webpack 多环境打包 | 能打出不同的包 |
📚 资源推荐与学习建议
Vue 2: 首选官方文档,中文资料丰富,非常详尽。之后可以结合一些实战视频教程,加深理解。
Element UI: 官方文档和示例代码非常完善,是学习的最佳资料。
Axios: 查阅其NPM页面或GitHub仓库,里面有丰富的API文档和示例。
微信OAuth: 认真阅读微信官方文档的“网页授权”章节,这是最权威的资料。
SSE: 学习
EventSource的MDN文档,并搜索“SSE 聊天室”、“SSE 打字机效果”等关键词,参考社区的最佳实践。学习心态:这条路线涉及的技术点较多,不要试图一次性掌握所有内容。可以按照我提供的阶段,分而治之,逐个击破。每完成一个阶段的实操任务,你都会获得实实在在的成就感。
