96SEO 2026-04-24 23:06 5
一个优秀的Web应用Ru果缺少了智Neng对话功Neng,仿佛就失去了灵魂。我们不再满足于枯燥的表单提交,用户渴望的是那种“有来有回”的即时反馈感。就像两个人面对面交谈,而不是在寄信。本节,我们将深入探讨如何利用Vue 3和TypeScript,构建一个不仅功Neng完备,而且视觉体验丝滑的智Neng对话界面。这不仅仅是代码的堆砌,geng是对用户体验的一次深度打磨。

在动手敲代码之前,我们需要先在脑海中构建起整个交互的蓝图。想象一下当你向ChatGPT提问时发生了什么?你的消息飞向服务器,服务器像流水一样一点点把答案推回来屏幕上的文字逐个蹦出,这种“打字机”效果正是现代AI应用的核心魅力所在。
为了实现这一点,我们将采用组件化的思维。整个页面被清晰地划分为三个区域:顶部的Header负责展示身份;中间的Messages Area是战场,承载着所有的对话历史;底部的Input Area则是发射台,负责收集用户的意图。这种布局结构稳固,不仅符合用户的视觉习惯,也为后续的响应式布局打下了基础。
┌─────────────────────────────┐
│ Header │ ← 固定头部
├─────────────────────────────┤
│ │
│ Messages Area │ ← 可滚动消息区
│ │
│ ┌─────────────────────┐ │
│ │ User Message │ │
│ └─────────────────────┘ │
│ │
│ ┌─────────────────────┐ │
│ │ AI Message │ │
│ └─────────────────────┘ │
│ │
├─────────────────────────────┤
│ ┌─────────┐ ┌────────┐ │
│ │ Input │ │ Send │ │ ← 固定输入区
│ └─────────┘ └────────┘ │
└─────────────────────────────┘
二、 后端连接:处理流式数据
传统的HTTP请求是“一问一答”的,但等待大模型生成全部文本再返回简直是灾难。我们需要引入Server-Sent Events 技术,让后端像倒水一样,生成多少就传多少。
在 src/api/chat.ts 中,我们封装了 streamChat 函数。这里有个小细节值得玩味:我们使用了 axios 的 onDownloadProgress。这通常被用来显示文件下载进度条,但在这里我们用它来拦截每一次数据包的到达。
从服务器传来的原始数据往往是一长串字符串,夹杂着 data: 前缀和换行符。我们需要像剥洋葱一样,一层层去掉这些外壳,提取出核心的JSON内容。代码中通过 slice 方法只处理新增的数据片段,避免重复解析,这在大文本流下Neng显著提升性Neng。当然别忘了处理那个特殊的 信号,它是服务器告诉我们要“闭嘴”的暗号。
import type { AxiosProgressEvent, GenericAbortSignal } from 'axios'
import { post } from './request'
export interface ChatRequest {
message: string
}
export interface ChatResponse {
data: any
message: string | null
status: string
}
/**
* 流式聊天 API - SSE 格式解析
* 这里我们利用 axios 的下载进度回调来模拟 SSE 读取
*/
export function streamChat(
data: ChatRequest,
onProgress: => void,
abortSignal?: GenericAbortSignal
) {
// 记录上一次处理到的数据长度,用于截取新增部分
let previousLength = 0
return post({
url: '/chat/ask',
data,
signal: abortSignal,
responseType: 'text', // 关键:必须设置为 text 才Neng获取原始流
onDownloadProgress: => {
// 获取当前Yi接收的完整响应文本
const rawData = progressEvent.event.target.response
if return
// 只截取新增的那部分数据进行处理
const newData = rawData.slice
previousLength = rawData.length
if return
// SSE 格式通常是 "data: {json}
"
const lines = newData.split
for {
if ) {
// 去掉前缀,提取纯内容
let dataContent = line.slice
// Ru果收到结束信号,直接跳过
if {
continue
}
// 处理转义字符,比如把
还原成真正的换行
dataContent = dataContent.replace
if {
// 每收到一块内容,立即触发回调,实现“流”的感觉
onProgress
}
}
}
},
})
}
三、 前端核心:Vue组件的响应式魔法
有了数据的源头,接下来就是如何在Vue中优雅地展示它们。在 src/components/ChatPage.vue 中,我们使用了 语法糖,这让代码逻辑geng加紧凑。
我们定义了一个 messages 数组,它是一个响应式引用。每当用户发送消息时我们先把用户的内容“塞”进去,紧接着再“塞”进去一个空的AI消息占位符。这个占位符非常关键,它告诉用户:“我听到了正在思考。”
这里有一个Vue 3的冷知识:当我们为了确保万无一失,我们使用了 triggerRef。这就像是给Vue系统发了一封加急邮件,强制它立刻geng新视图,不要偷懒。
import { ref, nextTick, onMounted, triggerRef } from 'vue'
import { useMessage } from 'naive-ui'
import { streamChat } from '../api/chat'
import { marked } from 'marked'
import hljs from 'highlight.js'
import 'highlight.js/styles/github-dark.css'
// 配置 marked 解析器
marked.setOptions({
breaks: true, // 启用换行符
gfm: true // 启用 GitHub 风格 Markdown
})
interface Message {
role: 'user' | 'assistant'
content: string
isStreaming?: boolean
}
const messages = ref
const inputMessage = ref
const isLoading = ref
const scrollbarRef = ref
const message = useMessage
let scrollTimer: number | null = null
// 核心发送逻辑
const sendMessage = async => {
if || isLoading.value) return
const userMessage = inputMessage.value.trim
inputMessage.value = '' // 清空输入框
// 1. 展示用户消息
messages.value.push({
role: 'user',
content: userMessage
})
// 2. 创建 AI 消息占位符
const aiMessage: Message = {
role: 'assistant',
content: '',
isStreaming: true
}
messages.value.push
isLoading.value = true
await nextTick
scrollToBottom
try {
// 3. 开启流式请求
await streamChat(
{ message: userMessage },
=> {
// 逐字追加内容,模拟打字机效果
aiMessage.content += content
// 强制geng新视图
triggerRef
// 平滑滚动到底部
debouncedScrollToBottom
}
)
// 4. 结束流式状态
aiMessage.isStreaming = false
triggerRef
} catch {
aiMessage.content = '抱歉,发送消息时出现错误。请检查网络连接和后端服务是否正常运行。'
aiMessage.isStreaming = false
message.error
} finally {
isLoading.value = false
await nextTick
scrollToBottom
}
}
2. 渲染引擎:Markdown与代码高亮
AI生成的回复往往包含代码块或复杂的格式。Ru果直接显示纯文本,那简直是对用户眼睛的摧残。我们引入了 marked 将Markdown转换为HTML,并配合 highlight.js 对代码块进行着色。
这里有个小坑:marked 解析出来的HTML实体可Neng会被转义。在传给 hljs 之前,我们需要把这些实体还原回来否则高亮库会一脸懵逼。下面的 renderMarkdown 函数就是专门处理这些脏活的。
// Markdown 渲染与代码高亮处理
const renderMarkdown = => {
if return ''
try {
let html = marked.parse as string
// 正则匹配代码块并进行高亮处理
html = html.replace"><\/code><\/pre>/g,
=> {
// 还原 HTML 实体字符
const decodedCode = code
.replace
.replace
.replace
.replace
.replace
// Ru果该语言支持高亮,则进行替换
if ) {
try {
const highlighted = hljs.highlight.value
return `${highlighted}
`
} catch {
// 高亮失败则回退
}
}
return match
})
return html
} catch {
return content
}
}
四、 细节决定成败:滚动与防抖
你有没有遇到过这种情况:AI正在疯狂输出,你想往上翻kan之前的对话,结果页面一直自动往下跳,把你拉回底部?这简直是令人抓狂的体验。
为了解决这个问题,我们引入了防抖滚动。在 debouncedScrollToBottom 函数中,我们设置了一个定时器。每当有新内容到来我们先清除上一次的滚动计划,重新计时。只有当内容停止geng新一小段时间后我们才真正执行滚动。这样既保证了用户Nengkan到Zui新内容,又给了用户“抢夺”滚动条控制权的机会。
// 防抖滚动逻辑
const debouncedScrollToBottom = => {
if {
clearTimeout
}
scrollTimer = setTimeout => {
scrollToBottom
}, 100)
}
// 执行滚动
const scrollToBottom = => {
if {
scrollbarRef.value.scrollTo({
position: 'bottom',
behavior: 'smooth'
})
}
}
五、 视觉美学:打造“Vibe”感
功Neng再强,Ru果界面丑陋也难以让人驻足。我们使用了Naive UI组件库,配合Tailwind CSS,打造了一种清新、现代的视觉风格。
注意kan模板部分的代码,我们大量使用了渐变色和阴影。用户的消息气泡使用了蓝色渐变,显得专业且冷静;AI的回复则使用了白色背景搭配绿色点缀,暗示着“智Neng”与“安全”。头部和底部的背景dou加了 backdrop-blur,这让界面在滚动时背景内容若隐若现,增加了层次感。
特别是那个“AI正在思考...”的加载动画,配合旋转的小图标,给了用户极佳的心理暗示。这种微交互虽然不起眼,但正是它们让整个应用显得有温度。
AI 聊天助手
通过本节的学习,我们不仅仅写出了一个聊天界面geng重要的是掌握了处理异步流式数据的方法论。从底层的SSE解析,到Vue组件的响应式geng新,再到CSS的视觉打磨,每一步dou不可或缺。
这就是“Vibe Coding”的魅力所在:先让功Neng跑起来然后再一点点把它雕琢成艺术品。现在的界面Yi经具备了智Neng对话的雏形,但我们的征途才刚刚开始。下一节,我们将挑战geng高维度的技Neng——实现数据分析可视化,让AI不仅Neng“说”,还Neng“画”出精彩的数据图表。敬请期待!
本节回顾:
核心技Neng: 掌握了基于 axios 的流式数据接收与解析技巧。
Vue技巧: 深入理解了 triggerRef 在高频geng新场景下的应用。
体验优化: 实现了防抖自动滚动,解决了流式阅读时的跳屏痛点。
视觉呈现: 集成了 Markdown 与代码高亮,提升了技术类对话的可读性。
前置知识: Vue 3 Composition API、TypeScript 基础、Axios 拦截器。
阅读时间: 约 15 分钟
难度级别: 实战进阶
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback