当前位置: 首页 > news >正文

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

<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="输入消息...">
  1. v-model="message":

    • v-model 是 Vue.js 中的一个指令,用于双向数据绑定。
    • 在这个例子中,v-model="message" 将输入框的值与 message 变量绑定在一起。每当用户在输入框中输入内容时,message 的值会自动更新;反之,如果 message 的值发生变化,输入框的内容也会相应地更新。
  2. @keydown.enter="sendMessage":

    • @keydown.enter 是 Vue.js 中的一种事件修饰符,用于监听键盘事件。
    • 在这个例子中,当用户按下回车键(enter)时,会触发 sendMessage 方法。
    • 这样设计的好处是用户可以直接通过回车键发送消息,而不需要点击发送按钮。

引入 UUID 生成库

import { v4 as uuidv4 } from 'uuid'; // 引入 UUID 生成库
  1. import { v4 as uuidv4 } from 'uuid':
    • 这行代码从 uuid 库中导入了 v4 方法,并将其重命名为 uuidv4
    • uuid 库是一个用于生成唯一标识符(UUID)的库,广泛用于生成唯一的字符串标识。
    • v4 是一种特定的 UUID 版本,生成的是随机的 UUID。

generateUUID 方法

const generateUUID = () => {return uuidv4(); // 生成全局唯一标识符
};
  1. 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;
};
  1. const createMessageElement = (text, alignment) => { ... }:

    • 这是一个箭头函数,定义了一个名为 createMessageElement 的方法。
    • 接受两个参数:text(消息内容)和 alignment(消息的对齐方式,如 message-left 或 message-right)。
  2. const messageElement = document.createElement('div'):

    • 创建一个新的 div 元素,用于表示一条消息。
  3. messageElement.className = message ${alignment}``:

    • 设置 div 元素的类名,包括固定的 message 类和动态的 alignment 类(如 message-left 或 message-right)。
  4. const textElement = document.createElement('span'):

    • 创建一个新的 span 元素,用于显示消息内容。
  5. textElement.textContent = text.length > 20 ? text.slice(0, 20) + '...' : text:

    • 设置 span 元素的文本内容。
    • 如果消息内容超过20个字符,则截取前20个字符并在末尾加上省略号 ...;否则直接使用原消息内容。
  6. messageElement.appendChild(textElement):

    • 将 span 元素添加到 div 元素中。
  7. 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;}};
};
  1. receiving.value = true:

    • 设置 receiving 标记为 true,表示正在接收消息。
  2. const url = "wss://backend.buildpicoapps.com/api/chatbot/chat":

    • 定义 WebSocket 连接的 URL。
  3. const websocket = new WebSocket(url):

    • 创建一个新的 WebSocket 实例,连接到指定的 URL。
  4. websocket.addEventListener("open", () => { ... }):

    • 监听 WebSocket 连接打开事件。
    • 当连接成功打开时,发送消息到服务器。
  5. websocket.send(JSON.stringify({ ... })):

    • 将消息对象序列化为 JSON 字符串,并通过 WebSocket 发送到服务器。
    • 消息对象包含 chatIdappIdsystemPrompt 和 message 等属性。
  6. const messageElement = createMessageElement("", "message-left"):

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

    • 将创建的消息元素添加到聊天记录显示区。
  8. websocket.onmessage = (event) => { ... }:

    • 监听 WebSocket 消息接收事件。
    • 当从服务器接收到消息时,将消息内容添加到消息元素中,并滚动到底部以确保最新消息可见。
  9. 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);}
};
  1. if (!receiving.value && message.value.trim() !== ""):

    • 检查是否正在接收消息且输入框中的内容不为空。
    • 如果条件满足,继续执行发送消息的操作。
  2. const messageText = message.value.trim():

    • 获取用户输入的消息,并去除首尾的空白字符。
  3. message.value = "":

    • 清空输入框的内容。
  4. const messageElement = createMessageElement(messageText, "message-right"):

    • 创建一个用户消息元素,设置对齐方式为 message-right,表示这是来自用户的消息。
  5. chatbox.value.appendChild(messageElement):

    • 将创建的消息元素添加到聊天记录显示区。
  6. chatbox.value.scrollTop = chatbox.value.scrollHeight:

    • 滚动到底部,确保最新消息可见。
  7. connectWebSocket(messageText):

    • 调用 connectWebSocket 方法,建立 WebSocket 连接并发送消息到服务器。

相关文章:

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

<template><div class"container"><!-- 页面头部 --><header><h1>跟它说说话吧&#xff01;</h1><p>一个活泼的伙伴&#xff0c;为你提供情感支持&#xff01;</p></header><!-- 聊天容器 --><div c…...

DICOM标准:深入详解DICOM医学影像中的传输语法

引言 DICOM&#xff08;数字成像和通信医学&#xff09;标准在医学影像数据交换中扮演着至关重要的角色。其中&#xff0c;*传输语法&#xff08;Transfer Syntax&#xff09;是DICOM标准中定义数据编码和传输方式的核心部分。理解传输语法对于确保不同设备和系统之间的互操作性…...

sql server 文件备份恢复

数据库介绍文件组 PRIMARY 文件 lys D:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\lys.mdf lys_02 D:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\lys_02.ndf文件组 sec 有2个表&#xff08;sec_1,sec_2&#xff09; 文件 …...

Gradle命令编译Android Studio工程项目并签名

文章目录 gradlew命令gradlew编译debug apkgradlew编译release apkapksigner签名apkgradlew注意事项 gradlew命令 gradlew 是一个脚本文件&#xff0c;它允许你在没有全局安装 Gradle 的情况下运行 Gradle 构建。这个脚本在多平台上可用&#xff0c;对于 Windows 系统来说是 g…...

lua入门教程:垃圾回收

Lua的垃圾回收机制是一种自动内存管理方式&#xff0c;用于回收不再被程序访问的对象&#xff0c;从而避免内存泄漏。以下是一个关于Lua垃圾回收机制的详细教程&#xff1a; 一、Lua垃圾回收机制概述 Lua使用自动内存管理&#xff0c;这意味着程序员不需要手动释放内存。Lua的…...

基于前后端分离架构,SaaS云平台与私有云部署的智慧校园源码,java电子班牌源码

基于前后端分离架构&#xff0c;SaaS云平台与私有云部署的智慧校园源码&#xff0c;java电子班牌源码&#xff0c;自主研发&#xff0c;自主版权&#xff0c;上百个学校应用案例&#xff0c;支持二次开发。 在信息技术飞速发展的今天&#xff0c;教育领域也迎来了一场革命性的变…...

知识总结五

一、C深浅拷贝 浅拷贝&#xff1a;只复制对象的成员变量的值&#xff0c;如果成员变量包含指针&#xff0c;则只复制指针值&#xff0c;不复制指针所指向的数据。深拷贝&#xff1a;复制对象的成员变量的值&#xff0c;并且如果成员变量包含指针&#xff0c;则还复制指针所指向…...

一、初识C语言(1)

1.C语言识别的是二进制语言 C语言是一门计算机语言&#xff0c;计算机是硬件&#xff0c;硬件分通电&#xff08;1&#xff09;和 未通电&#xff08;0&#xff09;两种情况&#xff0c;所以C语言识别的都是0 / 1信号&#xff0c;也就是二进制语言。 2.C语言文件类型以及基本框…...

petty 状态管理库文档

自研 Petty 状态管理库产生背景 petty 是一款适用于 vue2.5以下版本&#xff08;目前已兼容vue2.5x 以上版本&#xff09;的状态管理库&#xff0c;能够在 vue 2这种配置项的代码中&#xff0c;去实现类似于 vue3 里的 pinia、React 里的hook的调用形式&#xff0c;用函数式的…...

SpringMVC学习记录(三)之响应数据

SpringMVC学习记录&#xff08;三&#xff09;之响应数据 一、页面跳转控制1、快速返回模板视图2、转发和重定向 二、返回JSON数据1、前置准备2、ResponseBody 三、返回静态资源1、静态资源概念2、访问静态资源 /*** TODO: 一个controller的方法是控制层的一个处理器,我们称为h…...

ENSP GVRP动态学习VLAN

手工配置的VLAN称为静态VLAN&#xff0c;通过GVRP协议创建的VLAN称为动态VLAN。 GVRP有三种注册模式&#xff0c;不同的模式对静态VLAN和动态VLAN的处理方式也不同。 GVRP的三种注册模式分别定义如下&#xff1a; Normal模式&#xff1a;允许动态VLAN在端口上进行注册…...

怎么给llama3.2-vision:90b模型进行量化剪枝蒸馏

对 LLaMA 3.2 Vision: 90B 模型进行量化、剪枝和蒸馏&#xff0c;涉及到模型的压缩和优化技术&#xff0c;以减少其计算量和内存占用。以下是实现这些步骤的一般流程&#xff1a; 1. 量化 (Quantization) 量化的目的是减少模型的精度&#xff08;如从FP32到INT8&#xff09;&…...

flutter 专题四 Flutter渲染流程

一、 Widget - Element - RenderObject关系 二、 Widget 、Element 、RenderObject 分别表示什么 2.1 Widget Widget描述和配置子树的样子 Widget就是一个个描述文件&#xff0c;这些描述文件在我们进行状态改变时会不断的build。但是对于渲染对象来说&#xff0c;只会使用最…...

刘艳兵-DBA028-您可以在 ORCL1 和 ORCL2 数据库都运行其实例的主机上安装“独立服务器的 Oracle 网格基础结构“。哪两个陈述是正确的?

您可以在 ORCL1 和 ORCL2 数据库都运行其实例的主机上安装"独立服务器的 Oracle 网格基础结构"。哪两个陈述是正确的&#xff1f;&#xff08;选择两个&#xff09; A 在完成“用于独立服务器的Oracle Grid Infrastructure”安装后&#xff0c;必须使用crsctl sta…...

前端三件套-css

一、元素选择器 元素选择器&#xff1a;利用标签名称。p,h1-h6...... 行内样式&#xff08;内联样式&#xff09;&#xff1a;例如<p style"color:red;font-size:50px"> id选择器&#xff1a;针对某一个特定的标签来使用。以#定义。 class&#xff08;类&a…...

实验(未完成)

一、拓扑图 二、需求及分析 1、需求 按照图示的VLAN及IP地址需求&#xff0c;完成相关配置。 要求SW1为VLAN 2/3的主根及主网关&#xff0c;SW2为VLAN 20/30的主根及主网关。 SW1和SW2互为备份。 可以使用super vlan。 上层通过静态路由协议完成数据通信过程。 AR1为企…...

Python基础学习_01

目录 1、注释 2、数字和数学计算 3、变量 4、字符串 5、打印 6、本节总结 1、注释 • 什么是注释&#xff1f; 1&#xff09;注释就是用自然语言向代码阅读者说明代码的功能和意义 • 注释 1&#xff09;单行注释使用 # 为开头&#xff1b;并且不能换行…...

鸿萌数据迁移服务: 企业服务器整机在线热迁移, 实现不停机业务转移

天津鸿萌科贸发展有限公司从事数据安全服务二十余年&#xff0c;致力于为各领域客户提供专业的数据存储、数据恢复、数据备份、数据迁移等解决方案与服务&#xff0c;并针对企业面临的数据安全风险&#xff0c;提供专业的相关数据安全培训。 鸿萌数据迁移业务为众多企业顺利高效…...

【C】无类型指针及函数指针

一、无类型指针 &#xff08;1&#xff09;无类指针只包含内存地址&#xff0c;不知道内存地址从存放数据是什么类型&#xff1a; void *ptrNULL; &#xff08;2&#xff09;可以其他类型赋给无类型指针&#xff0c;但是无类型指针赋给有类型指针会警号&#xff1b; …...

VR的左右眼渲染方法

VR的左右眼视频渲染shader unity_StereoEyeIndex 结点可以判断当前渲染的时候左眼还是右眼&#xff0c;所以可以通过着色器来更根据当前眼睛使用不同的渲染方式达到左右眼渲染不同。 Shader "Unlit/VRVideoPlay" {Properties{_MainTex ("Texture", 2D) …...

爬虫-------字体反爬

目录 一、了解什么是字体加密 二. 定位字体位置 三. python处理字体 1. 工具库 2. 字体读取 3. 处理字体 案例1&#xff1a;起点 案例2&#xff1a;字符偏移&#xff1a; 5请求数据 - 发现偏移量 5.4 多套字体替换 套用模板 版本1 版本2 四.项目实战 1. 采集目…...

vue2组件封装和UI组件的二次封装,方法,属性,ref的传递

封装组件使用v-model 使用方法props接受value值&#xff0c;当值发生变化的时候再通过this.$emit("input", newValue)&#xff0c;则实现了简单组件的v-model封装,如果不使用第三方UI可以接受到的值使用watch或者计算属性保存&#xff0c;然后再通过事件派发自己保存…...

喜报!景联文科技成功通过DCMM数据管理能力成熟度二级认证

10月30日&#xff0c;中国电子信息行业联合会公示了新一批DCMM贯标企业&#xff0c;景联文科技成功通过DCMM数据管理能力成熟度二级认证&#xff08;乙方认证&#xff09;。 DCMM是《数据管理能力成熟度评估模型》的简称&#xff0c;是我国在数据管理领域首个正式发布的国家标准…...

从壹开始解读Yolov11【源码研读系列】——Data.dataset.py:模型训练数据预处理/YOLO官方数据集类——YOLODataset

【前情回顾】在上一篇文章记录了YOLO源码data目录下的 base.py 文件&#xff0c;其中定义了一个可灵活修改的数据加载处理基类——Class BaseDataset 灵活基类博文地址&#xff1a;https://blog.csdn.net/qq_58718853/article/details/143249295 【实验代码】所有实验代码上传至…...

C语言初阶必会的练习题(3)之位操作符(^ 、、>>等)的应用

C语言初阶必会的练习题&#xff08;3&#xff09; 放在最前面的1、不允许创建临时变量&#xff0c;交换两个整数的内容1.1、分析&#xff1a;见代码注释&#xff08;a&#xff09;方法 1&#xff08;b&#xff09;方法 2 1.2、结果展示方法 1 的 结果&#xff1a;方法 2 的 结果…...

MongoDB面试专题33道解析

大家好&#xff0c;我是 V 哥。今天给大家分享 MongoDB的道 V 哥原创的面试题&#xff0c;收藏起来&#xff0c;一定会对你有帮助。 V 哥推荐&#xff1a;2024 最适合入门的 JAVA 课程 1. 你说的 NoSQL 数据库是什么意思&#xff1f;NoSQL 与 RDBMS 直接有什么区别&#xff1f…...

Laravel 安全实践:如何防止 XSS 攻击

在当今的网络环境中&#xff0c;应用程序的安全性越来越受到开发者和企业的重视。跨站脚本攻击&#xff08;XSS&#xff09;是常见的网络安全威胁之一&#xff0c;它通过在目标网站上注入恶意脚本&#xff0c;窃取用户信息或执行恶意操作。作为流行的 PHP 框架&#xff0c;Lara…...

《Java Web 开发》

一、引言 在当今数字化时代&#xff0c;Web 应用程序已经成为人们生活和工作中不可或缺的一部分。Java Web 开发作为一种广泛应用的技术&#xff0c;以其强大的功能、稳定性和可扩展性&#xff0c;在企业级应用开发中占据着重要地位。本文将深入探讨 Java Web 开发的各个方面&a…...

Vector和ArrayList

Vector和ArrayList都是Java集合框架中的动态数组实现类&#xff0c;它们之间存在一些显著的区别。以下是对Vector和ArrayList的详细比较&#xff1a; 一、线程安全性 Vector&#xff1a;是线程安全的&#xff0c;即多线程情况下&#xff0c;Vector可以保证容器的同步性。Vect…...

关于我、重生到500年前凭借C语言改变世界科技vlog.16——万字详解指针概念及技巧

文章目录 1. sizeof 和 strlen1.1 sizeof1.2 strlen 2. 数组和指针结合的试题深入解析2.1 一维数组2.2 字符数组代码1代码2代码3代码4代码5代码6 2.3 二维数组 3.指针运算的试题深入解析题1题2题3题4题5题6题7 希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力…...