news 2026/10/26 11:59:48

Vue3实现轻量级ChatGPT前端:连续对话与Markdown渲染

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue3实现轻量级ChatGPT前端:连续对话与Markdown渲染

1. 项目背景与核心功能

去年ChatGPT刚发布时,我就在想:能不能自己写个前端应用,把它的API封装成更符合日常使用习惯的界面?当时市面上已有的客户端要么功能臃肿,要么缺少关键特性。经过几个周末的折腾,最终用Vue3实现了一个极简但实用的ChatGPT前端,核心解决了三个痛点:

  1. 连续对话:官方网页版虽然能记住上下文,但每次刷新就清零。我这个版本会把对话历史存在本地,重启浏览器也能继续聊。

  2. Markdown渲染:ChatGPT返回的代码块、表格等内容,在前端用marked.js实现语法高亮和格式美化,比纯文本友好得多。

  3. 轻量化设计:整个应用打包后不到200KB,没有冗余依赖,甚至能在10年前的电脑上流畅运行。

2. 技术选型与项目搭建

2.1 为什么选择Vue3

对比React和Svelte后选择Vue3的原因很实际:

  • 组合式API更适合封装聊天逻辑(后文会详细展示useChat这个hook)
  • 单文件组件让Markdown渲染和样式隔离更简单
  • Vite的启动速度比Webpack快5倍以上,适合快速迭代

创建项目时推荐用以下命令:

npm create vite@latest chatgpt-web --template vue-ts

2.2 关键依赖清单

{ "dependencies": { "vue": "^3.3.0", "marked": "^5.0.0", // Markdown解析 "highlight.js": "^11.0.0", // 代码高亮 "pinia": "^2.0.0" // 状态管理 } }

注意:不要安装官方OpenAI库,直接用fetch调用API。第三方库会增加打包体积,而且我们只需要最基础的POST功能。

3. 核心功能实现详解

3.1 连续对话的本地存储方案

实现本地记忆的关键是合理设计数据结构。我的方案是:

interface Message { role: 'user' | 'assistant' content: string timestamp: number } const chatHistory = useLocalStorage<Message[]>('chat-history', [])

在Pinia中封装存储逻辑:

export const useChatStore = defineStore('chat', { actions: { addMessage(message: Message) { // 限制最多存储50条消息 if (this.messages.length > 50) { this.messages.shift() } this.messages.push(message) } } })

3.2 Markdown渲染的优化技巧

直接使用marked会有XSS风险,需要配置sanitizer:

import { marked } from 'marked' import DOMPurify from 'dompurify' marked.setOptions({ highlight: (code) => hljs.highlightAuto(code).value }) const safeMarkdown = (raw: string) => { return DOMPurify.sanitize(marked.parse(raw)) }

样式优化建议:

/* 让代码块有更好的视觉区分 */ pre { background: #f8f8f8; border-radius: 6px; padding: 12px; overflow-x: auto; } /* 表格添加斑马纹 */ table tr:nth-child(even) { background: #f2f2f2; }

3.3 API调用的防抖与错误处理

ChatGPT API有时响应较慢,需要做请求管理:

let controller: AbortController | null = null const fetchAIResponse = async (messages: Message[]) => { // 取消上一个未完成的请求 if (controller) controller.abort() controller = new AbortController() try { const response = await fetch('https://api.openai.com/v1/chat/completions', { signal: controller.signal, method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${import.meta.env.VITE_OPENAI_KEY}` }, body: JSON.stringify({ model: 'gpt-3.5-turbo', messages }) }) if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`) return await response.json() } finally { controller = null } }

4. 实战中的性能优化

4.1 虚拟滚动优化长对话列表

当聊天记录超过50条时,使用vue-virtual-scroller提升性能:

<template> <RecycleScroller :items="messages" :item-size="80" key-field="timestamp" > <template #default="{ item }"> <div class="message"> <!-- 消息内容渲染 --> </div> </template> </RecycleScroller> </template>

4.2 智能缓存策略

对常见问题答案进行本地缓存:

const cachedAnswers = new Map<string, string>() const getCachedAnswer = (question: string) => { const key = question.trim().toLowerCase() return cachedAnswers.get(key) }

5. 常见问题与解决方案

5.1 如何处理API限流?

实测发现两个有效策略:

  1. 指数退避重试:首次失败后等待1秒,第二次等待2秒,第三次4秒...
  2. 请求队列:当同时触发多个请求时,用队列顺序处理
const requestQueue: (() => Promise<void>)[] = [] let isProcessing = false const processQueue = async () => { if (isProcessing || requestQueue.length === 0) return isProcessing = true const task = requestQueue.shift() await task?.() isProcessing = false processQueue() }

5.2 移动端适配技巧

在手机上有两个关键调整:

  1. 输入框使用position: fixed固定在底部
  2. 启用iOS的弹性滚动:
body { -webkit-overflow-scrolling: touch; }

6. 项目部署与后续迭代

6.1 最简单的部署方案

用Vercel或Netlify可以免费部署:

  1. 在项目根目录创建vercel.json
{ "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }] }
  1. 连接Git仓库自动部署

6.2 值得添加的功能

  1. 对话标签管理:给不同对话打标签方便检索
  2. 预设Prompt模板:一键插入常用提问模板
  3. API用量统计:监控token消耗情况

这个项目的核心价值在于:用最精简的代码实现了ChatGPT最实用的功能。去掉所有花哨的UI,专注于提升对话体验。如果你也想自己定制AI助手,不妨从这个最小可行版本开始迭代。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/26 11:59:15

CXL事务层拆解:请求类型、通道配对与Bias Flip验证

上一篇文章把 CXL 协议栈从链路层往上捋&#xff0c;停在事务层门口——528 位 FLIT 怎么切槽位、CXL.io 和 CXL.cachemem 怎么在同一个物理通道里挤着走、CRC 放在哪几个 bit。发出去以后后台收到的问题很集中&#xff1a;请求类型那么多到底怎么选、Bias Flip 里的 GO 和 GO_…

作者头像 李华
网站建设 2026/10/26 11:58:46

C++静态反射实现无编译器内建的类型特性检测

1. 项目概述&#xff1a;当编译器不再提供类型特性支持时 在C模板元编程领域&#xff0c;类型特性(Type Traits)一直是编译期类型检测的核心工具。传统实现高度依赖编译器内置函数(intrinsics)&#xff0c;这带来了两个根本性限制&#xff1a;一是移植性问题&#xff0c;不同编…

作者头像 李华
网站建设 2026/10/26 11:58:19

claude-mem:为对话式AI构建持久化记忆系统的架构设计与工程实践

1. 项目缘起与核心定位 第一次看到 claude-mem 这个标题&#xff0c;我的直觉是&#xff1a;这大概率是一个围绕 Claude 生态做“记忆层”的项目。为什么这么判断&#xff1f;因为 Claude 本身是一个对话式的大模型&#xff0c;它有一个天然的短板—— 上下文窗口是有限的&a…

作者头像 李华
网站建设 2026/10/26 11:57:18

西门子PLC与C#上位机通讯开发实战指南

1. 西门子PLC与C#上位机通讯开发实战 在工业自动化领域&#xff0c;PLC与上位机的通讯一直是核心需求。我最近完成了一个基于西门子S7系列PLC和C# WPF的上位机开发项目&#xff0c;使用开源的S7netplus库实现了稳定可靠的通讯&#xff0c;并自定义了部分功能模块。这套方案已经…

作者头像 李华
网站建设 2026/10/26 11:56:47

XPath语法详解与Web数据抓取实战技巧

1. 为什么我们需要XPath&#xff1f; 在Web数据抓取和XML文档处理中&#xff0c;我们经常需要精准定位文档中的特定元素。想象一下&#xff0c;你面前有一本结构复杂的百科全书&#xff0c;而XPath就是让你能直接说出"我要第三章节第二段落的第五句话"的神奇语言。 …

作者头像 李华
网站建设 2026/10/26 11:56:46

深入解析Shim技术:原理、应用与实战案例

1. 应用程序重定向技术&#xff08;Shim&#xff09;的本质与起源 2006年微软发布的Application Compatibility Toolkit&#xff08;ACT&#xff09;工具包中首次正式引入了Shim技术这个概念。当时Windows Vista刚刚发布&#xff0c;大量旧版应用程序在新系统上出现兼容性问题。…

作者头像 李华