基于Vue3构建Deepseek/ChatGPT流式聊天界面:API对接与开发实践指南
2025.09.17 15:48浏览量:0简介:本文详细解析如何使用Vue3开发仿Deepseek/ChatGPT的流式聊天AI界面,并完成与Deepseek/OpenAI API的对接,涵盖界面设计、流式响应处理、错误处理及优化策略。
基于Vue3构建Deepseek/ChatGPT流式聊天界面:API对接与开发实践指南
一、项目背景与需求分析
随着生成式AI技术的普及,用户对交互体验的要求日益提升。Deepseek与ChatGPT等AI模型通过流式响应(Streaming Response)技术,实现了边生成边显示的效果,显著提升了对话的流畅性。本文以Vue3为核心框架,结合Composition API与TypeScript,实现一个支持流式响应的聊天界面,并完成与Deepseek/OpenAI API的对接。
核心需求
- 流式响应:实时显示AI生成的文本,避免长时间等待。
- 界面仿制:复现Deepseek/ChatGPT的简洁交互风格。
- API兼容:支持Deepseek与OpenAI API的灵活切换。
- 错误处理:网络中断、API限额等异常场景的友好提示。
二、技术选型与架构设计
1. 前端框架选择
Vue3的Composition API与响应式系统天然适合处理动态数据流。结合<script setup>
语法,代码更简洁。
2. 核心依赖
- axios:HTTP请求库,支持请求取消与拦截器。
- EventSource:处理Server-Sent Events(SSE),实现流式响应。
- Pinia:状态管理,替代Vuex,简化全局状态共享。
3. 架构分层
src/
├── api/ # API请求封装
│ ├── deepseek.ts
│ └── openai.ts
├── components/ # UI组件
│ ├── ChatBubble.vue
│ └── MessageList.vue
├── composables/ # 组合式函数
│ └── useStream.ts
├── stores/ # Pinia状态
│ └── chat.ts
└── App.vue # 根组件
三、流式聊天界面实现
1. 界面布局设计
采用“消息气泡+输入框”的经典布局,关键点:
- 消息方向:用户消息右对齐,AI消息左对齐。
- 动态高度:消息容器自动扩展,避免滚动条跳动。
- 加载指示器:流式响应时显示“正在生成…”动画。
<!-- MessageList.vue -->
<template>
<div class="message-container">
<div
v-for="(msg, index) in messages"
:key="index"
:class="['message', msg.sender]"
>
<div v-if="msg.streaming" class="streaming-dots">•••</div>
<div v-else>{{ msg.content }}</div>
</div>
</div>
</template>
<style scoped>
.message {
margin: 12px;
padding: 10px 15px;
border-radius: 18px;
max-width: 80%;
}
.message.user {
background: #e3f2fd;
align-self: flex-end;
}
.message.ai {
background: #f1f1f1;
align-self: flex-start;
}
.streaming-dots {
font-size: 16px;
animation: blink 1.4s infinite;
}
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
</style>
2. 流式响应处理
使用EventSource
监听服务器推送的文本片段,关键代码:
// useStream.ts
import { ref, onUnmounted } from 'vue';
export function useStream(url: string, onMessage: (chunk: string) => void) {
const eventSource = new EventSource(url);
const isStreaming = ref(true);
eventSource.onmessage = (event) => {
if (event.data === '[DONE]') {
isStreaming.value = false;
eventSource.close();
return;
}
onMessage(event.data);
};
eventSource.onerror = () => {
isStreaming.value = false;
eventSource.close();
};
onUnmounted(() => {
eventSource.close();
});
return { isStreaming };
}
3. API对接实现
Deepseek API示例
// api/deepseek.ts
import axios from 'axios';
export async function callDeepseek(prompt: string) {
const response = await axios.post('https://api.deepseek.com/v1/chat', {
model: 'deepseek-chat',
messages: [{ role: 'user', content: prompt }],
stream: true,
});
return new ReadableStream({
start(controller) {
const reader = response.data.body.getReader();
function pump() {
reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
const text = new TextDecoder().decode(value);
controller.enqueue(text);
pump();
});
}
pump();
},
});
}
OpenAI API示例
// api/openai.ts
export async function callOpenAI(prompt: string) {
const eventSource = new EventSource(
`https://api.openai.com/v1/chat/completions?stream=true`,
{
headers: {
'Authorization': `Bearer ${import.meta.env.VITE_OPENAI_KEY}`,
'Content-Type': 'application/json',
},
method: 'POST',
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: prompt }],
stream: true,
}),
}
);
return eventSource;
}
四、核心功能实现
1. 消息状态管理
使用Pinia管理消息列表与当前输入:
// stores/chat.ts
import { defineStore } from 'pinia';
export const useChatStore = defineStore('chat', {
state: () => ({
messages: [] as { sender: 'user' | 'ai'; content: string; streaming?: boolean }[],
input: '',
}),
actions: {
addUserMessage(content: string) {
this.messages.push({ sender: 'user', content });
this.input = '';
},
addAIMessage(content: string, streaming = false) {
this.messages.push({ sender: 'ai', content, streaming });
},
},
});
2. 发送消息与流式处理
<!-- App.vue -->
<script setup>
import { useChatStore } from './stores/chat';
import { useStream } from './composables/useStream';
const chatStore = useChatStore();
const { isStreaming } = useStream(apiUrl, (chunk) => {
const lastMsg = chatStore.messages[chatStore.messages.length - 1];
if (lastMsg?.sender === 'ai' && lastMsg.streaming) {
lastMsg.content += chunk;
}
});
const sendMessage = async () => {
if (!chatStore.input.trim()) return;
chatStore.addUserMessage(chatStore.input);
chatStore.addAIMessage('', true); // 初始化流式消息
try {
// 根据配置调用Deepseek或OpenAI
const response = await callDeepseek(chatStore.input);
// 或 const response = await callOpenAI(chatStore.input);
// 处理响应...
} catch (error) {
chatStore.messages.pop(); // 移除未完成的AI消息
alert('API调用失败');
}
};
</script>
五、优化与错误处理
1. 性能优化
- 防抖输入:避免频繁触发API请求。
- 虚拟滚动:长消息列表时使用
vue-virtual-scroller
。 - 请求取消:切换对话时取消未完成的流式请求。
// api/utils.ts
import axios from 'axios';
const source = axios.CancelToken.source();
export function cancelRequest() {
source.cancel('请求已取消');
}
2. 错误处理策略
- 网络中断:重试机制或显示离线模式。
- API限额:提示用户升级套餐或切换模型。
- 内容过滤:检测敏感词并中断响应。
六、部署与扩展建议
1. 环境变量配置
# .env.production
VITE_API_BASE_URL=https://api.example.com
VITE_OPENAI_KEY=sk-xxxxxxxxxx
2. 多模型支持
通过配置文件动态切换API:
// config.ts
export const API_CONFIG = {
default: 'deepseek',
models: {
deepseek: {
url: 'https://api.deepseek.com',
auth: null, // 或Bearer Token
},
openai: {
url: 'https://api.openai.com',
auth: import.meta.env.VITE_OPENAI_KEY,
},
},
};
3. 扩展功能
七、总结与展望
本文通过Vue3实现了仿Deepseek/ChatGPT的流式聊天界面,并完成了与主流AI API的对接。核心价值在于:
- 低延迟交互:流式响应提升用户体验。
- 技术复用:组件与逻辑可迁移至其他AI应用。
- API抽象:支持多模型无缝切换。
未来可探索的方向包括:
- WebSocket替代SSE实现更低延迟。
- 端到端加密保障对话隐私。
- 结合WebAssembly优化本地推理性能。
通过模块化设计与清晰的分层架构,本项目可作为企业级AI聊天应用的开发模板,快速适配不同业务场景。
发表评论
登录后可评论,请前往 登录 或 注册