<template> <div class="container"> <!-- 页面头部 --> <header> <h1>跟它说说话吧!</h1> <p>一个活泼的伙伴,为你提供情感支持!</p> </header> <!-- 聊天容器 --> <div class="chat-container"> <!-- 聊天记录显示区 --> <div id="chatbox" ref="chatbox" class="chatbox"></div> <!-- 输入框和发送按钮 --> <div class="input-container"> <input v-model="message" @keydown.enter="sendMessage" placeholder="输入消息..."> <button @click="sendMessage">? 发送消息!</button> </div> </div> </div></template><script setup>import { ref, onMounted } from 'vue';import { v4 as uuidv4 } from 'uuid'; // 引入 UUID 生成库// 响应式数据const message = ref(''); // 用户输入的消息const chatbox = ref(null); // 聊天记录显示区的引用const chatId = ref(uuidv4()); // 当前会话的唯一标识符const receiving = ref(false); // 标记是否正在接收消息const systemPrompt = ref("你是一只活泼可爱的宠物狗,模拟微信聊天应用中的对话。你的任务是为用户提供情感支持和陪伴。记住用户的对话内容,并在短时间内做出相关回应。消息气泡的大小应根据内容长度自动调整。"); // 系统提示信息// 方法const generateUUID = () => { return uuidv4(); // 生成全局唯一标识符};const createMessageElement = (text, alignment) => { const messageElement = document.createElement('div'); messageElement.className = `message ${alignment}`; // 设置消息的对齐方式 const textElement = document.createElement('span'); // 如果消息内容超过20个字符,则截取前20个字符并加上省略号 textElement.textContent = text.length > 20 ? text.slice(0, 20) + '...' : text; messageElement.appendChild(textElement); return messageElement;};const connectWebSocket = (message) => { receiving.value = true; // 标记正在接收消息 const url = "your-chat-url"; const websocket = new WebSocket(url); websocket.addEventListener("open", () => { // 发送消息到服务器 websocket.send( JSON.stringify({ chatId: chatId.value, appId: "nothing-include", systemPrompt: systemPrompt.value, message: message }) ); }); // 创建一个空的消息元素,用于显示从服务器接收到的消息 const messageElement = createMessageElement("", "message-left"); chatbox.value.appendChild(messageElement); websocket.onmessage = (event) => { // 将接收到的消息添加到消息元素中 messageElement.innerText += event.data; // 滚动到底部,确保最新消息可见 chatbox.value.scrollTop = chatbox.value.scrollHeight; }; websocket.onclose = (event) => { if (event.code === 1000) { receiving.value = false; // 正常关闭连接 } else { // 处理非正常关闭连接的情况 messageElement.textContent += "无法从服务器获取回复。请刷新页面并重试。"; chatbox.value.scrollTop = chatbox.value.scrollHeight; receiving.value = false; } };};const sendMessage = () => { if (!receiving.value && message.value.trim() !== "") { const messageText = message.value.trim(); // 获取用户输入的消息 message.value = ""; // 清空输入框 // 创建用户消息元素 const messageElement = createMessageElement(messageText, "message-right"); chatbox.value.appendChild(messageElement); // 添加到聊天记录显示区 // 滚动到底部,确保最新消息可见 chatbox.value.scrollTop = chatbox.value.scrollHeight; // 发送消息到服务器 connectWebSocket(messageText); }};// 生命周期钩子onMounted(() => { // 初始化操作 chatbox.value.scrollTop = chatbox.value.scrollHeight;});</script><style>body { /* 页面背景渐变色 */ background: linear-gradient(to right, rgb(249, 244, 200), rgb(249, 244, 240));}.container { /* 容器内边距 */ padding: 16px;}header { /* 页面头部居中对齐 */ text-align: center; margin-bottom: 16px;}h1 { /* 标题样式 */ font-size: 24px; font-weight: bold; color: #1a53ff;}p { /* 描述文字颜色 */ color: #6b7280;}.chat-container { /* 聊天容器最大宽度 */ width: 100%; max-width: 600px; /* 阴影效果和圆角 */ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); border-radius: 8px; overflow: hidden; margin: 0 auto; /* 居中 */}.chatbox { /* 聊天记录显示区布局 */ display: flex; flex-direction: column; align-items: flex-start; padding: 16px; height: 384px; overflow-y: auto; /* 自动滚动条 */}.message { /* 消息样式 */ display: inline-block; margin: 10px 0; padding: 10px; border-radius: 12px; color: white;}.message-left { /* 来自机器人的消息样式 */ background-color: #1a53ff; align-self: flex-start;}.message-right { /* 来自用户的消息样式 */ background-color: #10b981; align-self: flex-end;}.input-container { /* 输入框和按钮容器布局 */ display: flex; flex-direction: row; margin: 16px 0; padding: 8px; border-top: 1px solid #d1d5db;}input { /* 输入框样式 */ flex-grow: 1; padding: 8px; border: 1px solid #d1d5db; border-radius: 8px; margin-right: 8px;}button { /* 发送按钮样式 */ background-color: #1a53ff; border-radius: 8px; padding: 8px 16px; color: white; font-weight: bold;}</style>
效果图 有帮助点个赞吧~
<input>
元素的绑定
<input v-model="message" @keydown.enter="sendMessage" placeholder="输入消息...">
v-model="message"
:
v-model
是 Vue.js 中的一个指令,用于双向数据绑定。在这个例子中,v-model="message"
将输入框的值与 message
变量绑定在一起。每当用户在输入框中输入内容时,message
的值会自动更新;反之,如果 message
的值发生变化,输入框的内容也会相应地更新。 @keydown.enter="sendMessage"
:
@keydown.enter
是 Vue.js 中的一种事件修饰符,用于监听键盘事件。在这个例子中,当用户按下回车键(enter
)时,会触发 sendMessage
方法。这样设计的好处是用户可以直接通过回车键发送消息,而不需要点击发送按钮。 引入 UUID 生成库
import { v4 as uuidv4 } from 'uuid'; // 引入 UUID 生成库
import { v4 as uuidv4 } from 'uuid'
: 这行代码从 uuid
库中导入了 v4
方法,并将其重命名为 uuidv4
。uuid
库是一个用于生成唯一标识符(UUID)的库,广泛用于生成唯一的字符串标识。v4
是一种特定的 UUID 版本,生成的是随机的 UUID。 generateUUID
方法
const generateUUID = () => { return uuidv4(); // 生成全局唯一标识符};
const generateUUID = () => { ... }
: 这是一个箭头函数,定义了一个名为 generateUUID
的方法。该方法内部调用了 uuidv4()
函数,生成一个全局唯一的标识符(UUID)。返回生成的 UUID 字符串。 其他方法
createMessageElement
const createMessageElement = (text, alignment) => { const messageElement = document.createElement('div'); messageElement.className = `message ${alignment}`; // 设置消息的对齐方式 const textElement = document.createElement('span'); // 如果消息内容超过20个字符,则截取前20个字符并加上省略号 textElement.textContent = text.length > 20 ? text.slice(0, 20) + '...' : text; messageElement.appendChild(textElement); return messageElement;};
const createMessageElement = (text, alignment) => { ... }
:
createMessageElement
的方法。接受两个参数:text
(消息内容)和 alignment
(消息的对齐方式,如 message-left
或 message-right
)。 const messageElement = document.createElement('div')
:
div
元素,用于表示一条消息。 messageElement.className =
message ${alignment}``:
div
元素的类名,包括固定的 message
类和动态的 alignment
类(如 message-left
或 message-right
)。 const textElement = document.createElement('span')
:
span
元素,用于显示消息内容。 textElement.textContent = text.length > 20 ? text.slice(0, 20) + '...' : text
:
span
元素的文本内容。如果消息内容超过20个字符,则截取前20个字符并在末尾加上省略号 ...
;否则直接使用原消息内容。 messageElement.appendChild(textElement)
:
span
元素添加到 div
元素中。 return messageElement
:
connectWebSocket
const connectWebSocket = (message) => { receiving.value = true; // 标记正在接收消息 const url = "wss://backend.buildpicoapps.com/api/chatbot/chat"; const websocket = new WebSocket(url); websocket.addEventListener("open", () => { // 发送消息到服务器 websocket.send( JSON.stringify({ chatId: chatId.value, appId: "nothing-include", systemPrompt: systemPrompt.value, message: message }) ); }); // 创建一个空的消息元素,用于显示从服务器接收到的消息 const messageElement = createMessageElement("", "message-left"); chatbox.value.appendChild(messageElement); websocket.onmessage = (event) => { // 将接收到的消息添加到消息元素中 messageElement.innerText += event.data; // 滚动到底部,确保最新消息可见 chatbox.value.scrollTop = chatbox.value.scrollHeight; }; websocket.onclose = (event) => { if (event.code === 1000) { receiving.value = false; // 正常关闭连接 } else { // 处理非正常关闭连接的情况 messageElement.textContent += "无法从服务器获取回复。请刷新页面并重试。"; chatbox.value.scrollTop = chatbox.value.scrollHeight; receiving.value = false; } };};
receiving.value = true
:
receiving
标记为 true
,表示正在接收消息。 const url = "wss://backend.buildpicoapps.com/api/chatbot/chat"
:
const websocket = new WebSocket(url)
:
websocket.addEventListener("open", () => { ... })
:
websocket.send(JSON.stringify({ ... }))
:
chatId
、appId
、systemPrompt
和 message
等属性。 const messageElement = createMessageElement("", "message-left")
:
message-left
,表示这是来自机器人的消息。 chatbox.value.appendChild(messageElement)
:
websocket.onmessage = (event) => { ... }
:
websocket.onclose = (event) => { ... }
:
sendMessage
const sendMessage = () => { if (!receiving.value && message.value.trim() !== "") { const messageText = message.value.trim(); // 获取用户输入的消息 message.value = ""; // 清空输入框 // 创建用户消息元素 const messageElement = createMessageElement(messageText, "message-right"); chatbox.value.appendChild(messageElement); // 添加到聊天记录显示区 // 滚动到底部,确保最新消息可见 chatbox.value.scrollTop = chatbox.value.scrollHeight; // 发送消息到服务器 connectWebSocket(messageText); }};
if (!receiving.value && message.value.trim() !== "")
:
const messageText = message.value.trim()
:
message.value = ""
:
const messageElement = createMessageElement(messageText, "message-right")
:
message-right
,表示这是来自用户的消息。 chatbox.value.appendChild(messageElement)
:
chatbox.value.scrollTop = chatbox.value.scrollHeight
:
connectWebSocket(messageText)
:
connectWebSocket
方法,建立 WebSocket 连接并发送消息到服务器。