共计 2576 个字符,预计需要花费 7 分钟才能阅读完成。
背景与痛点
在现代 Web 应用中,实时聊天界面已成为标配,但实现过程中常遇到以下技术挑战:

- 消息排序问题:异步请求导致消息到达顺序不可控
- 状态同步难题:多端登录时对话状态的一致性维护
- 性能开销:长时间对话导致内存占用过高
- 流式响应处理:大语言模型的渐进式响应渲染
- 错误恢复机制:网络中断后的消息重传策略
技术选型
通信协议对比
- WebSocket
- 优点:全双工通信,低延迟
- 缺点:需要额外维护连接状态
- SSE(Server-Sent Events)
- 优点:HTTP 协议兼容,自动重连
- 缺点:仅支持服务端推送
- 轮询(Polling)
- 优点:实现简单
- 缺点:资源浪费严重
最终选择:对于 ChatGPT 类应用,推荐 SSE 方案,因其:
- 天然支持流式响应
- 自动处理断线重连
- 无需额外端口配置
核心实现
状态管理(Composition API)
interface Message {
id: string
role: 'user' | 'assistant'
content: string
timestamp: number
status?: 'pending' | 'error' | 'success'
}
const useChatStore = () => {const messages = ref<Message[]>([])
const addMessage = (msg: Message) => {messages.value.push(msg)
}
const updateMessage = (id: string, updates: Partial<Message>) => {const index = messages.value.findIndex(m => m.id === id)
if (index >= 0) {messages.value[index] = {...messages.value[index], ...updates }
}
}
return {messages, addMessage, updateMessage}
}
流式消息处理
const handleSSE = async () => {const eventSource = new EventSource('/api/chat')
eventSource.onmessage = (event) => {const data = JSON.parse(event.data)
if (data.type === 'delta') {
// 增量更新消息内容
store.updateMessage(data.id, {content: prev => prev + data.content})
}
if (data.type === 'complete') {store.updateMessage(data.id, { status: 'success'})
eventSource.close()}
}
eventSource.onerror = () => {store.updateMessage(currentMsgId, { status: 'error'})
eventSource.close()}
}
本地存储策略
// 使用 IndexedDB 存储历史对话
const saveHistory = debounce(() => {const dbRequest = indexedDB.open('ChatDB', 1)
dbRequest.onsuccess = (e) => {
const db = e.target.result
const tx = db.transaction('conversations', 'readwrite')
tx.objectStore('conversations').put({
id: conversationId,
messages: store.messages,
updatedAt: Date.now()})
}
}, 1000)
性能优化
虚拟滚动实现
<template>
<RecycleScroller
:items="messages"
:item-size="72"
key-field="id"
>
<template #default="{item}">
<MessageBubble :message="item" />
</template>
</RecycleScroller>
</template>
请求优化策略
- 防抖处理:
const sendMessage = debounce(async (content: string) => {// 发送逻辑}, 300) - 缓存策略:
const cachedResponses = new Map<string, string>() const getCachedResponse = (prompt: string) => {const hash = md5(prompt) return cachedResponses.get(hash) }
生产环境避坑指南
跨域解决方案
- Nginx 配置示例:
location /api/ { proxy_pass http://backend; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
移动端适配
- 输入框防遮挡:
.input-area { position: fixed; bottom: env(safe-area-inset-bottom); padding-bottom: constant(safe-area-inset-bottom); }
敏感内容过滤
const containsSensitiveContent = (text: string) => {const patterns = [/badword1/i, /badword2/i]
return patterns.some(p => p.test(text))
}
延伸思考
未来可扩展方向:
- 多模态支持:
- 使用
<input type="file">接收图片 - Web Audio API 处理语音
- 对话持久化:
- 使用 WebRTC 实现 P2P 对话同步
- 性能监控:
- 添加 Performance API 检测渲染耗时
总结
本文完整实现了基于 Vue 3 的 ChatGPT 风格对话框,关键技术点包括:
- 使用 SSE 处理流式响应
- Composition API 管理复杂状态
- 虚拟滚动优化长列表性能
- 完善的错误处理和本地持久化
实际项目中还需根据具体需求调整消息压缩策略、添加打字机动画等增强用户体验的细节。完整示例代码已发布在 GitHub 仓库,欢迎交流改进建议。
正文完
