当前位置:首页 » 《关注互联网》 » 正文

基于vue3实现的聊天机器人前端(附代码)

9 人参与  2024年11月16日 16:41  分类 : 《关注互联网》  评论

点击全文阅读


<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 方法,并将其重命名为 uuidv4uuid 库是一个用于生成唯一标识符(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":

定义 WebSocket 连接的 URL。

const websocket = new WebSocket(url):

创建一个新的 WebSocket 实例,连接到指定的 URL。

websocket.addEventListener("open", () => { ... }):

监听 WebSocket 连接打开事件。当连接成功打开时,发送消息到服务器。

websocket.send(JSON.stringify({ ... })):

将消息对象序列化为 JSON 字符串,并通过 WebSocket 发送到服务器。消息对象包含 chatIdappIdsystemPrompt 和 message 等属性。

const messageElement = createMessageElement("", "message-left"):

创建一个空的消息元素,用于显示从服务器接收到的消息。设置对齐方式为 message-left,表示这是来自机器人的消息。

chatbox.value.appendChild(messageElement):

将创建的消息元素添加到聊天记录显示区。

websocket.onmessage = (event) => { ... }:

监听 WebSocket 消息接收事件。当从服务器接收到消息时,将消息内容添加到消息元素中,并滚动到底部以确保最新消息可见。

websocket.onclose = (event) => { ... }:

监听 WebSocket 连接关闭事件。根据关闭代码判断连接是否正常关闭。如果是非正常关闭,显示错误信息并滚动到底部。
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 连接并发送消息到服务器。

点击全文阅读


本文链接:http://zhangshiyu.com/post/187240.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1