uniapp中的流式輸出

一、完整代碼展示

  • 目前大多數的ai對話都是流式輸出,也就是對話是一個字或者多個字逐一進行顯示的
  • 下面是一個完整的流式顯示程序,包含的用戶的消息發出和ai的消息回復
<template><view class="chat-container"><view class="messages"><!-- 對話氣泡 --><viewv-for="(message, index) in messages":key="index":class="['message', message.sender]"><text selectable="true">{{ message.text }}</text></view><!-- 加載狀態 --><view v-if="isLoading" class="loading-spinner"></view></view><!-- 消息輸入和發送按鈕 --><view class="input-area"><textareav-model="inputMessage"placeholder="輸入消息"@input="adjustInputHeight"></textarea><button @click="sendMessage">發送</button></view></view>
</template><script>
export default {data() {return {messages: [],inputMessage: '',isLoading: false,inputHeight: 48};},methods: {sendMessage() {//如果輸出消息為空直接返回if (!this.inputMessage.trim()) return;// 添加用戶消息this.messages.push({text: this.inputMessage,sender: 'user'});// 初始化AI消息const aiIndex = this.messages.length;this.messages.push({text: '',sender: 'ai'});// 重置輸入this.inputMessage = '';this.isLoading = true;// 發起流式請求const url = 'http://localhost:8081/chat';const params = {session_id: 'token',content: this.inputMessage};uni.request({url: url + '?' + this.serializeParams(params),method: 'GET',header: {'Accept': 'text/event-stream',},success: (res) => {this.processStreamResponse(res.data, aiIndex);},fail: (err) => {console.error('請求失敗:', err);this.isLoading = false;}});},processStreamResponse(data, aiIndex) {const chunks = data.split('\n');let chunkIndex = 0;const interval = setInterval(() => {if (chunkIndex >= chunks.length) {clearInterval(interval);this.isLoading = false;return;}const chunk = chunks[chunkIndex].replace('data:', '').trim();if (chunk) {this.messages[aiIndex].text += chunk;this.$forceUpdate();}chunkIndex++;}, 50);},serializeParams(params) {return Object.entries(params).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join('&');},adjustInputHeight(e) {const textarea = e.target;textarea.style.height = 'auto';textarea.style.height = textarea.scrollHeight + 'px';this.inputHeight = textarea.scrollHeight;}}
};
</script><style>
.chat-container {height: 100vh;display: flex;flex-direction: column;padding: 20px;background-color: #f5f5f7;
}.messages {flex: 1;overflow-y: auto;padding: 20px;
}.message {margin: 10px 0;padding: 12px 16px;border-radius: 16px;max-width: 70%;word-wrap: break-word;
}.message.user {background: linear-gradient(135deg, #cbe7ff, #cfe9ff);align-self: flex-end;
}.message.ai {background: linear-gradient(135deg, #f0f0f0, #e0e0e0);align-self: flex-start;
}.loading-spinner {border: 4px solid #f3f3f3;border-top: 4px solid #007aff;border-radius: 50%;width: 24px;height: 24px;animation: spin 1s linear infinite;margin: 20px auto;
}.input-area {display: flex;gap: 10px;margin-top: 20px;
}textarea {flex: 1;padding: 12px;border: 1px solid #ddd;border-radius: 8px;resize: none;
}button {padding: 12px 24px;background-color: #007aff;color: white;border: none;border-radius: 8px;cursor: pointer;
}@keyframes spin {0% { transform: rotate(0deg); }100% { transform: rotate(360deg); }
}
</style>

二、流式傳輸核心代碼講解

1、請求發起

  • 設置Accept: text/event-stream告知服務器需要流式響應
  • 通過session_id傳遞認證信息
  • 使用GET請求發送消息內容
uni.request({url: url + '?' + this.serializeParams(params),method: 'GET',header: {'Accept': 'text/event-stream',},success: (res) => {this.processStreamResponse(res.data, aiIndex);}
});

2、流式響應處理

  • 將響應數據按換行符分割成塊
  • 使用setInterval控制顯示速度(這里設置為 50ms / 塊)
  • 逐塊追加到 AI 消息中
  • 使用$forceUpdate強制刷新視圖
processStreamResponse(data, aiIndex) {const chunks = data.split('\n');let chunkIndex = 0;const interval = setInterval(() => {if (chunkIndex >= chunks.length) {clearInterval(interval);this.isLoading = false;return;}const chunk = chunks[chunkIndex].replace('data:', '').trim();if (chunk) {this.messages[aiIndex].text += chunk;this.$forceUpdate();}chunkIndex++;}, 50);
}

3、加載狀態管理

  • 在請求發起時顯示加載狀態
  • 響應處理完成后隱藏加載狀態
// 發送消息時
this.isLoading = true;// 響應處理完成
clearInterval(interval);
this.isLoading = false;

4、數據格式處理?

  • 將參數對象序列化為 URL 查詢字符串
  • 使用encodeURIComponent處理特殊字符
serializeParams(params) {return Object.entries(params).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join('&');
}

5、消息顯示?

  • 使用 flex 布局實現消息氣泡
  • 通過selectable="true"實現文本選中
  • 根據 sender 添加不同樣式
<view v-for="(message, index) in messages" :class="['message', message.sender]"><text selectable="true">{{ message.text }}</text>
</view>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/899590.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/899590.shtml
英文地址,請注明出處:http://en.pswp.cn/news/899590.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

洛谷題單1-P5703 【深基2.例5】蘋果采購-python-流程圖重構

題目描述 現在需要采購一些蘋果&#xff0c;每名同學都可以分到固定數量的蘋果&#xff0c;并且已經知道了同學的數量&#xff0c;請問需要采購多少個蘋果&#xff1f; 輸入格式 輸入兩個不超過 1 0 9 10^9 109 正整數&#xff0c;分別表示每人分到的數量和同學的人數。 輸…

JS 手撕題高頻考點

前端面試中&#xff0c;JS 手撕題是高頻考點&#xff0c;主要考察 編程能力、算法思維、JS 核心知識。以下是最常見的手撕題分類 代碼示例&#xff1a; 目錄 &#x1f4cc; 1. 手寫函數柯里化&#x1f4cc; 2. 手寫 debounce&#xff08;防抖&#xff09;&#x1f4cc; 3. 手寫…

【STM32】知識點介紹一:硬件知識

文章目錄 一、電源引腳簡介二、電平信號三、電路分析 一、電源引腳簡介 VCC、GND、VDD和VSS是電子電路中常見的術語&#xff0c;代表著不同的電源引腳或電壓。 VCC&#xff08;Voltage at the Common Collector&#xff09;&#xff1a;VCC是指集電極&#xff08;Collector&am…

3. 列表元素替換

【問題描述】給定一個列表&#xff0c;將列表中所有的偶數替換為0 【輸入形式】輸入一行&#xff0c;包含若干個整數&#xff0c;用空格分隔 【輸出形式】輸出替換后的列表&#xff0c;每個元素用空格分隔 【樣例輸入】1 2 3 4 5 6 7 8 9 10 【樣例輸出】1 0 3 0 5 0 7 0 9…

問題的根源還是解題的方案

周末的早上照例是要早醒 debug 代碼的&#xff0c;仿佛又回到了 2014 年… 古人幾天甚至幾個月不洗澡&#xff0c;不會臭嗎&#xff1f;有沒有可能古人沒有化纖類衣服&#xff0c;且古人的純天然生活環境其身體菌群和現代人不同&#xff0c;古人就像健康的野生動物一樣即使不洗…

虛擬機安裝linux系統無法上網的解決方法

在虛擬環境中運行Linux系統時&#xff0c;有時會遇到網絡連接問題&#xff0c;特別是在使用虛擬機軟件如VMware或VirtualBox時。本文將詳細介紹一種針對“虛擬機安裝Linux系統無法上網”問題的解決方案&#xff0c;以CentOS 6.5為例&#xff0c;適用于其他基于NAT模式的虛擬機環…

子網劃分淺度解析

文章目錄 ip地址的組成不同類型ip地址的范圍子網掩碼默認子網掩碼子網掩碼如何作用的&#xff1f;默認子網掩碼怎么作用&#xff1f; ip地址的組成 ip地址一般寫作4位點分十進制&#xff08;x.x.x.x&#xff09;&#xff0c;他們由32位二進制組成&#xff0c;每個x由8位二進制…

什么是 SEO(搜索引擎優化)?

您有網站嗎&#xff0c;或者您正在考慮創建一個網站&#xff1f;您想吸引更多人加入您的業務嗎&#xff1f;如果答案是肯定的&#xff0c;那么毫無疑問&#xff1a;SEO 應該是您營銷工作的一部分。這是建立品牌和吸引用戶訪問您的網站的好方法。但它實際上意味著什么呢&#xf…

鴻蒙HarmonyOS NEXT設備升級應用數據遷移流程

數據遷移是什么 什么是數據遷移&#xff0c;對用戶來講就是本地數據的遷移&#xff0c;終端設備從HarmonyOS 3.1 Release API 9及之前版本&#xff08;單框架&#xff09;遷移到HarmonyOS NEXT&#xff08;雙框架&#xff09;后保證本地數據不丟失。例如&#xff0c;我在某APP…

【現代深度學習技術】現代卷積神經網絡04:含并行連接的網絡(GoogLeNet)

【作者主頁】Francek Chen 【專欄介紹】 ? ? ?PyTorch深度學習 ? ? ? 深度學習 (DL, Deep Learning) 特指基于深層神經網絡模型和方法的機器學習。它是在統計機器學習、人工神經網絡等算法模型基礎上&#xff0c;結合當代大數據和大算力的發展而發展出來的。深度學習最重…

【ESP32】ESP32與MQTT通信:實現傳感器數據監測與設備控制

ESP32與MQTT通信 1 項目概覽2 硬件組成3 MQTT協議解析MQTT協議簡介MQTT核心概念本項目中的MQTT應用 4 MQTT Broker選擇EMQX Broker其他常用MQTT Broker 5 代碼解析初始化與配置MQTT消息處理發布傳感器數據 6 MQTT話題TOPIC設計7 EMQX的優勢在IoT項目中的體現8 MQTT通信流程9 應…

[特殊字符]《Curve DAO 系統學習目錄》

本教程旨在系統學習 Curve DAO 項目的整體架構、核心機制、合約設計、治理邏輯與代幣經濟等內容&#xff0c;幫助開發者全面理解其設計理念及運作方式。 目錄總覽&#xff1a; 1. Curve 項目概覽 ? 1.1 Curve 是什么&#xff1f;主要解決什么問題&#xff1f; ? 1.2 與其他…

每天一篇目標檢測文獻(六)——Part One

今天看的是《Object Detection with Deep Learning: A Review》 目錄 一、摘要 1.1 原文 1.2 翻譯 二、介紹 2.1 信息區域選擇 2.2 特征提取 2.3 分類 三、深度學習的簡要回顧 3.1 歷史、誕生、衰落和繁榮 3.2 CNN架構和優勢 一、摘要 1.1 原文 Due to object dete…

Arthas線上問題診斷器

Arthas是Alibaba開源的java診斷工具 解決問題 這個類從哪個jar 包加載的&#xff1f;為什么會報各種相關的Exception&#xff1f; 遇到問題無法在線上debug&#xff0c;不能直通過加載日志再重新發布 有什么辦法可以監控到JVM的實時運行狀態&#xff1f; …

[Lc5_dfs+floodfill] 簡介 | 圖像渲染 | 島嶼數量

目錄 0.floodfill算法簡介 1.圖像渲染 題解 2.島嶼數量 題解 之前我們在 bfs 中有介紹過[Lc15_bfsfloodfill] 圖像渲染 | 島嶼數量 | 島嶼的最大面積 | 被圍繞的區域&#xff0c;現在我們來看看 dfs 又是如何解決的呢 0.floodfill算法簡介 floodfill算法又叫洪水灌溉或者…

JVM類加載器詳解

文章目錄 1.類與類加載器2.類加載器加載規則3.JVM 中內置的三個重要類加載器為什么 獲取到 ClassLoader 為null就是 BootstrapClassLoader 加載的呢&#xff1f; 4.自定義類加載器什么時候需要自定義類加載器代碼示例 5.雙親委派模式類與類加載器雙親委派模型雙親委派模型的執行…

Chapters 15 16:What Is Architecture?Independence_《clean architecture》notes

What Is Architecture?&Independence **Chapter 15: What Is Architecture?****Key Concepts**:**Code Example: Layered Architecture**: **Chapter 16: Independence****Key Concepts**:**Code Example: Dependency Inversion & Interfaces**: **Combined Example:…

【SPP】RFCOMM 層在SPP中互操作性要求深度解析

藍牙串口協議&#xff08;SPP&#xff09;通過 RFCOMM 協議實現 RS232 串口仿真&#xff0c;其互操作性是設備互聯的關鍵。本文基于藍牙核心規范&#xff0c;深度解析 RFCOMM 層的能力矩陣、信號處理、流控機制及實戰開發&#xff0c;結合狀態機、流程圖和代碼示例&#xff0c;…

阻塞式IO與非阻塞IO的區別

阻塞式IO與非阻塞IO的區別 1. 阻塞式IO (Blocking I/O) 定義 當程序發起一個I/O操作&#xff08;如讀取文件、網絡數據&#xff09;時&#xff0c;進程會被掛起&#xff08;阻塞&#xff09;&#xff0c;直到操作完成或超時才會繼續執行后續代碼。在此期間&#xff0c;程序無法…

Gossip協議:分布式系統中的“八卦”傳播藝術

目錄 一、 什么是Gossip協議&#xff1f;二、 Gossip協議的應用 &#x1f4a1;三、 Gossip協議消息傳播模式詳解 &#x1f4da;四、 Gossip協議的優缺點五、 總結&#xff1a; &#x1f31f;我的其他文章也講解的比較有趣&#x1f601;&#xff0c;如果喜歡博主的講解方式&…