vue Ai 流试回答实现打字效果
注意需要下载两个依赖
//它能将markdown语法,实时转换为Html
import { marked } from "marked";
import { EventSourcePolyfill } from "event-source-polyfill";
<template><div v-html="valueContent"></div>
</template>
let speed = 20; // 字符显示速度(毫秒/字符)let lastTimestamp = 0;let AIstatus = 0; // 0 未开始 1 进行中 2 结束 let thinkContent = ""; //问题思考let valueContent = ""; //总结结果let output = "";let eventSource = null;let typingQueue: any = [];let animationFrameId: number | null = null; // 用于保存requestAnimationFrame的IDcloseSSE() {this.stopStreaming();this.AIstatus = 0;}get_thinkContent_valueContent(html: string) {let isf = false;if (html.indexOf("</think>") !== -1) {isf = true;}if (!isf) {//将markdown语法,实时转换为Htmlthis.thinkContent = marked(html).replace(/<pre>/g, "<pre class='hljs'>");} else {//获取到总结结果this.loading = false;let x = html.indexOf("</think>") || 0;if (x !== -1) {x += 8;}const x2 = html.substr(x);//将markdown语法,实时转换为Htmlthis.valueContent = marked(x2).replace(/<pre>/g, "<pre class='hljs'>");}}typeNextInQueue() {if (this.typingQueue && this.typingQueue.length) {const htmlContent = this.typingQueue[0] || "";this.output += htmlContent;this.get_thinkContent_valueContent(this.output);this.typingQueue.shift();}}typeWriter(timestamp: any) {if (!this.lastTimestamp) {this.lastTimestamp = timestamp;}const elapsed = timestamp - this.lastTimestamp;if (elapsed >= this.speed) {this.lastTimestamp = timestamp;//结束打印if (this.typingQueue.length === 0 && this.AIstatus === 2) {this.$nextTick(() => {this.initEcharts();this.initEcharts2();this.initEcharts3();});console.log(this.output);return; // 结束动画}this.typeNextInQueue();}this.animationFrameId = requestAnimationFrame(this.typeWriter);}processChunk(event: any) {if (!event.data) return;try {const decodedData = JSON.parse(event.data);const answer = decodedData.answer;const type = decodedData.event;if (type === "message_end") {this.AIstatus = 2;this.loading = false;}if (type === "message") {this.typingQueue.push(answer);}} catch (error) {}}stopStreaming() {if (this.eventSource) {this.eventSource?.close();this.eventSource = null;}}//点击开始搜索async getAiLiveHoodAiQaStream(content: any) {this.valueContent = "";this.output = "";this.typingQueue = [];this.AIstatus = 0;this.eventSource ? this.eventSource.close() : "";this.eventSource = null;console.log(content);const url = `${baseURL}/*****?content=${encodeURIComponent(content)}`;setTimeout(() => {this.loading = true;}, 50);const source = new EventSourcePolyfill(url, {headers: {"content-type": "application/json",token: ''}});requestAnimationFrame(this.typeWriter);this.eventSource = source;// 监听数据流source.addEventListener("message", event => {this.processChunk(event);});// 监听错误source.addEventListener("error", event => {console.log(event);this.stopStreaming();});// 连接错误处理source.onerror = error => {console.log(event);this.stopStreaming();};}//关闭弹窗handleClose(){this.valueContent = "";this.output = "";this.typingQueue = [];this.AIstatus = 2;this.eventSource ? this.eventSource.close() : "";this.eventSource = null;// 暂停requestAnimationFrame动画if (this.animationFrameId) {cancelAnimationFrame(this.animationFrameId);this.animationFrameId = null;}this.visibles = false;}
接口返回的格式,根据以上代码可以实现GPT打字效果。