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

基于vue3+pinia2仿ChatGPT聊天实例|vite4.x仿chatgpt界面

使用vue3+pinia2开发仿制chatgpt界面聊天实例Vue3-Chatgpt

基于Vue3.x+Pinia2+VueRouter+Vue3-Markdown等技术构建仿ChatGPT网页端聊天程序。支持经典+分栏界面布局、light/dark模式、全屏+半屏显示、Markdown语法解析、侧边栏隐藏等功能。

在这里插入图片描述
在这里插入图片描述

技术框架

  • 编辑工具:Cursor
  • 框架技术:Vue3+Vite4.x+Pinia2
  • 组件库:VEPlus (基于vue3桌面端组件库)
  • 国际化多语言:vue-i18n^9.2.2
  • 代码高亮:highlight.js^11.7.0
  • 本地存储:pinia-plugin-persistedstate^3.1.0
  • markdown解析:vue3-markdown-it

在这里插入图片描述
在这里插入图片描述

项目目录结构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

vite.config.js配置

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import { parseEnv } from './src/utils/env'// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {const viteEnv = loadEnv(mode, process.cwd())const env = parseEnv(viteEnv)return {plugins: [vue()],// base: '/',// mode: 'development', // development|production/*构建选项*/build: {// minify: 'esbuild', // 打包方式 esbuild(打包快)|terser// chunkSizeWarningLimit: 2000, // 打包大小警告// rollupOptions: {// 	output: {// 		chunkFileNames: 'assets/js/[name]-[hash].js',// 		entryFileNames: 'assets/js/[name]-[hash].js',// 		assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',// 	}// }},esbuild: {// 打包去除 console.log 和 debuggerdrop: env.VITE_DROP_CONSOLE ? ['console', 'debugger'] : []},/*开发服务器选项*/server: {// 端口port: env.VITE_PORT,// 是否浏览器自动打开open: env.VITE_OPEN,// 开启httpshttps: env.VITE_HTTPS,// 代理配置proxy: {// ...}},resolve: {// 设置别名alias: {'@': resolve(__dirname, 'src'),'@assets': resolve(__dirname, 'src/assets'),'@components': resolve(__dirname, 'src/components'),'@views': resolve(__dirname, 'src/views'),// 解决vue-i18n警告提示:You are running the esm-bundler build of vue-i18n.'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js'}}}
})

main.js主入口

import { createApp } from 'vue'
import App from './App.vue'// 引入Router和Store
import Router from './router'
import Store from './store'// 引入插件配置
import Plugins from './plugins'const app = createApp(App)app
.use(Router)
.use(Store)
.use(Plugins)
.mount('#app')

vue3.x组件库

项目中使用的组件库是基于vue3自定义UI组件库Ve-plus。一个支持40+组件的轻量级组件库。
在这里插入图片描述

在这里插入图片描述
安装组件

yarn add ve-plus
npm i ve-plus --save

https://blog.csdn.net/yanxinyun1990/article/details/129312570

整体布局

项目支持2种布局模式,整体分为顶栏+侧边栏+主体内容三大模块构成。
在这里插入图片描述

在这里插入图片描述

<div class="ve__layout-body flex1 flexbox"><!-- //中间栏 --><div class="ve__layout-menus flexbox" :class="{'hidden': store.config.collapse}"><aside class="ve__layout-aside flexbox flex-col"><ChatNew /><Scrollbar class="flex1" autohide size="4" gap="1"><ChatList /></Scrollbar><ExtraLink /><Collapse /></aside></div><!-- //右边栏 --><div class="ve__layout-main flex1 flexbox flex-col"><!-- 主内容区 --><Main /></div>
</div>
<template><div class="vegpt__editor"><div class="vegpt__editor-inner"><Flex :gap="0"><Popover placement="top" trigger="click" width="150"><Button class="btn" type="link" icon="ve-icon-yuyin1" v-tooltip="{content: '发送语音', theme: 'light', arrow: false}"></Button><template #content><div class="flexbox flex-alignc flex-col" style="padding: 15px 0;"><Icon name="ve-icon-yuyin" size="40" color="#0fa27e" /><p class="fs-12 mb-15 c-999">网络不给力</p><Button size="small"><i style="background:#f00;border-radius:50%;box-shadow:0 1px 2px #999;margin-right:5px;height:8px;width:8px;"></i>开始讲话</Button></div></template></Popover><Button class="btn" type="link" v-tooltip="{content: '发送图片', theme: 'light', arrow: false}"><Icon name="ve-icon-photo" size="16" cursor /><input ref="uploadImgRef" type="file" title="" accept="image/*" @change="handleUploadImage" /></Button><Inputclass="flex1"ref="editorRef"v-model="editorText"type="textarea":autosize="{maxRows: 4}"clearableplaceholder="Prompt..."@keydown="handleKeydown"@clear="handleClear"style="margin: 0 5px;"/><Button class="btn" type="link" icon="ve-icon-submit" @click="handleSubmit"></Button></Flex></div></div>
</template>
import { ref, watch } from 'vue'
import { guid } from '@/utils'
import { chatStore } from '@/store/modules/chat'const props = defineProps({value: { type: [String, Number] }
})
const emit = defineEmits(['clear'])const chatState = chatStore()const uploadImgRef = ref()
const editorRef = ref()
const editorText = ref(props.value)// ...// 发送会话
const handleSubmit = () => {editorRef.value.focus()if(!editorText.value) returnlet data = {type: 'text',role: 'User',key: guid(),content: editorText.value}chatState.addSession(data)// 清空editorText.value = ''
}
const handleKeydown = (e) => {// ctrl+enterif(e.ctrlKey && e.keyCode == 13) {handleSubmit()}
}
const handleClear = () => {emit('clear')
}
// 选择图片
const handleUploadImage = () => {let file = uploadImgRef.value.files[0]if(!file) returnlet size = Math.floor(file.size / 1024)console.log(size)if(size > 2*1024) {Message.danger('图片大小不能超过2M')uploadImgRef.value.value = ''return false}let reader = new FileReader()reader.readAsDataURL(file)reader.onload = function() {let img = this.resultlet data = {type: 'image',role: 'User',key: guid(),content: img}chatState.addSession(data)}
}

在这里插入图片描述

/*** 聊天状态管理* @author YXY  Q:282310962*/import { defineStore } from 'pinia'
import { guid, isEmpty } from '@/utils'export const chatStore = defineStore('chat', {state: () => ({// 聊天会话记录sessionId: '',session: []}),getters: {},actions: {// 创建新会话createSession(ssid) {this.sessionId = ssidthis.session.push({sessionId: ssid,title: '',data: []})},// 新增会话addSession(message) {// 判断当前会话uuid是否存在,不存在创建新会话if(!this.sessionId) {const ssid = guid()this.createSession(ssid)}this.session.map(item => {if(item.sessionId == this.sessionId) {if(!item.title) {item.title = message.content}item.data.push(message)}})// ...},// 获取会话getSession() {return this.session.find(item => item.sessionId == this.sessionId)},// 移除会话removeSession(ssid) {const index = this.session.findIndex(item => item?.sessionId === ssid)if(index > -1) {this.session.splice(index, 1)}this.sessionId = ''},// 删除某一条会话deleteSession(ssid) {// ...},// 清空会话clearSession() {this.session = []this.sessionId = ''}},// 本地持久化存储(默认存储localStorage)persist: true/* persist: {// key: 'chatStore', // 不设置则是默认appstorage: localStorage,paths: ['aa', 'bb'] // 设置缓存键} */
})

好了,基于vue3+vite4+pinia2开发模仿chatgpt聊天就分享到这里。

Tauri-Vue3聊天实例|Tauri跨端聊天
uniapp-ttlive短视频聊天|uniapp+uview仿抖音实例

在这里插入图片描述

相关文章:

基于vue3+pinia2仿ChatGPT聊天实例|vite4.x仿chatgpt界面

使用vue3pinia2开发仿制chatgpt界面聊天实例Vue3-Chatgpt 基于Vue3.xPinia2VueRouterVue3-Markdown等技术构建仿ChatGPT网页端聊天程序。支持经典分栏界面布局、light/dark模式、全屏半屏显示、Markdown语法解析、侧边栏隐藏等功能。 技术框架 编辑工具&#xff1a;Cursor框架…...

JDK动态代理和CGLIB动态代理

JDK动态代理和CGLIB动态代理 JDK动态代理和CGLIB动态代理 JDK动态代理和CGLIB动态代理 ① JDK动态代理只提供接口的代理&#xff0c;不支持类的代理&#xff0c;要求被代理类实现接口。JDK动态代理的核心是InvocationHandler接口和Proxy类&#xff0c;在获取代理对象时&#x…...

Jetpack Hilt 框架的基本使用

什么是 Hilt&#xff1f; Hilt 是一个功能强大、用法简单的依赖注入框架&#xff0c;于 2020 年加入到 Jetpack 家族中。它是 Android 团队联系了 Dagger2 团队&#xff0c;一起开发出来的一个专门面向 Android 的依赖注入框架。相比于 Dagger2&#xff0c;Hilt 最明显的特征就…...

exec()在不同namespace执行结果的区别

记录一个很tricky的问题&#xff0c;下面这段code在执行func1时会出现NameError: name List is not defined&#xff0c;但执行func2时一切正常。 import typescontent """ from typing import Listclass GeneratedData:qna: List"""def func1…...

人工智能革命中的22个隐藏职业:推动科技行业的变革

作者 | Manas Sadangi 随着人工智能技术的不断发展&#xff0c;它正在创造一系列前所未有的就业机会。虽然数据科学家、机器学习工程师和人工智能研究人员等传统的人工智能角色得到了广泛认可&#xff0c;但在推动科技行业变革方面&#xff0c;还有一些鲜为人知的职业同样重要。…...

算法题3 — 求字符串中的最长子串

文章目录 题目示例示例1示例2示例3 解题解法1解法2 leetcode 题目 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 示例1 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所以其长度为 3。 示例…...

【FreeRTOS】——中断优先级设置中断相关寄存器临界段代码保护调度器挂起与恢复

目录 前言&#xff1a; 一、中断优先级设置 二、中断相关寄存器&#xff08;STM32-Cortex M3&#xff09; 三、临界段代码保护 四、任务调度器的挂起和恢复 总结&#xff1a; 前言&#xff1a; 博客笔记根据正点原子视频教程编辑&#xff0c;仅供学习交流使用&#xff0…...

1.2 什么是eBPF?(下)

四,eBPF的优势 4.1 eBPF程序的动态加载 eBPF程序可以动态地加载到内核中,或从内核中删除。这个要与内核模块的加载与卸载区分开来。这里顺便讨论下eBPF程序与内核模块的区别,如下: 而Linux内核模块是面向内核API编程的,可以直接运行在内核当中。eBPF程序是面向BPF体系结构…...

掌握哪些测试技术才能说自己已经学成了?

一、过硬的基础能力 其实所有的测试大佬都是从底层基础开始的&#xff0c;随着时间&#xff0c;经验的积累慢慢变成大佬。要想稳扎稳打在测试行业深耕&#xff0c;成为测试大牛&#xff0c;首当其冲的肯定就是拥有过硬的基础&#xff0c;所有的基础都是根基&#xff0c;后期所…...

什么是C语言?

C语言是一种高级编程语言&#xff0c;于1972年由Dennis Ritchie在贝尔实验室开发出来。它是一种通用的、结构化的编程语言&#xff0c;被广泛用于系统软件、嵌入式系统、游戏开发以及科学计算等领域。 C语言的设计目标是提供一种简洁、高效、可移植的编程语言&#xff0c;以便…...

SAP-物料主数据-质量管理视图字段解析

过账到质检库存&#xff1a;要勾选&#xff0c;否则收货后库存不进入质检库存HU检验&#xff1a;收货到启用HU管理的库位时产生检验批&#xff0c;例如某个成品物料是收货到C002库位&#xff0c;该库位启用了HU管理&#xff0c;那么此处要勾选。但是如果勾选了&#xff0c;却收…...

TOP RPA·脱普×实在丨日用品企业脱普签约实在智能,构建全域数据智能运营系统

近日&#xff0c;实在智能与脱普日用化学品&#xff08;中国&#xff09;有限公司&#xff08;简称“脱普企业”&#xff09;在脱普企业上海总部举行“全域数据智能运营”项目启动会&#xff0c;双方领导及项目组关键成员共同参会&#xff0c;就项目目标、实施进程、沟通机制等…...

【Android】Handler(四)Looper的相关知识点

Handler 机制是 Android 多线程间通信的一种常见方式。每个 Handler 对象由一个 Looper 和一个 MessageQueue 组成&#xff0c;用于将 Message 对象处理到指定的线程中。通过创建 Handler 实例&#xff0c;在子线程中创建 Message 对象并通过sendMessage()方法发送给 Handler&a…...

Redis缓存雪崩及解决办法

缓存雪崩 1.缓存雪崩是指在同- -时段大量的缓存key同时失效或者Redis服务宕机&#xff0c;导致大量请求到 达数据库&#xff0c;带来巨大压力。 2.解决方案: ◆给不同的Key的TTL添加随机值 ◆利用Redis集群提高服务的可用性 ◆给缓存业务添加降级限流策略 降级可做为系统的保底…...

Maven私服仓库配置-Nexus详解

目录 一、什么是Maven私服&#xff1f;二、Maven 私服优势三、Maven 私服搭建四、Sonatype Nexus介绍五、Nexus仓库属性和分类六、Nexus仓库配置以及创建仓库七、Nexus配置用户角色八、Maven SNAPSHOT(快照)九、项目当中配置Nexus上传依赖十、项目当中配置Nexus下载依赖十一、测…...

Systrace系列10 —— Binder 和锁竞争解读

本文主要是对 Systrace 中的 Binder 和锁信息进行简单介绍,简单介绍了 Binder 的情况,介绍了 Systrace 中 Binder 通信的表现形式,以及 Binder 信息查看,SystemServer 锁竞争分析等。 Binder 概述 Android 的大部分进程间通信都使用 Binder,这里对 Binder 不做过多的解释…...

React Hooks中使用useState异步回调获取不到最新值的问题

ReactHook中useState异步回调获取不到最新值及解决⽅案 预先了解 setState 的两种传参⽅式 1、直接传⼊新值 setState(options); 列如&#xff1a; const [state, setState] useState(0); setState(state 1); 2、传⼊回调函数 setState(callBack); 例如&#xff1a; …...

JavaScript 高级 (完结)

目录 深浅拷贝 浅拷贝 深拷贝 递归实现深拷贝 js库lodash里面cloneDeep内部实现了深拷贝 JSON序列化 异常处理 throw 抛异常 try /catch 捕获异常 debugg 处理this this指向 普通函数 箭头函数 改变this call() apply() bind() call apply bind 总结 性能优化…...

【P30】JMeter 事务控制器(Transaction Controller)

文章目录 一、事务控制器&#xff08;Transaction Controller&#xff09;参数说明二、测试计划设计2.2.1、勾选 Generate parent sample2.2.1、勾选 Include duration of timer and pre-post processors in generated sample 一、事务控制器&#xff08;Transaction Controlle…...

【MySQL】MySQL的事务原理和实现?

文章目录 MySQL事务的底层实现原理一、事务的目的可靠性和并发处理 二、实现事务功能的三个技术2.1 redo log 与 undo log介绍2.1.1 redo log2.1.2undo log 2.2 mysql锁技术2.2.1 mysql锁技术 2.3 MVCC基础 三、事务的实现3.1 原子性的实现3.1.1 undo log 的生成3.1.2 根据undo…...

Kandinsky-5.0-I2V-Lite-5s性能调优教程:采样步数24平衡效率与质量实测

Kandinsky-5.0-I2V-Lite-5s性能调优教程&#xff1a;采样步数24平衡效率与质量实测 1. 模型简介与核心能力 Kandinsky-5.0-I2V-Lite-5s是一款专为单卡环境优化的轻量级图生视频模型。它能够将静态图片转化为约5秒时长的动态视频&#xff08;24fps&#xff09;&#xff0c;只需…...

墨语灵犀网络安全知识库:基于AI的威胁情报分析与解读

墨语灵犀网络安全知识库&#xff1a;让AI成为你的安全分析师 最近和几个做安全运营的朋友聊天&#xff0c;他们都在抱怨同一件事&#xff1a;每天面对海量的安全告警和晦涩的漏洞报告&#xff0c;眼睛都快看花了。一份新的漏洞描述扔过来&#xff0c;光是理解它到底在说什么、…...

OpenClaw备份方案:Qwen2.5-VL-7B技能与配置的定期同步

OpenClaw备份方案&#xff1a;Qwen2.5-VL-7B技能与配置的定期同步 1. 为什么需要备份OpenClaw系统 上周我的开发机突然蓝屏&#xff0c;硬盘分区表损坏。当我重装系统后&#xff0c;发现过去三个月精心调教的OpenClaw配置全部丢失——包括调试好的技能参数、对接的飞书机器人…...

Cesium实战:5分钟搞定飞机轨迹飞行与流光道路效果(附完整代码)

Cesium实战&#xff1a;5分钟实现飞机轨迹飞行与流光道路特效 第一次接触Cesium时&#xff0c;我就被它强大的三维地理可视化能力震撼了。作为一个长期从事WebGIS开发的工程师&#xff0c;我一直在寻找能够快速实现复杂三维场景的工具。直到遇到Cesium.js&#xff0c;才发现原来…...

lite-avatar形象库效果展示:教师数字人在直播授课场景中的眼神交互与手势模拟

lite-avatar形象库效果展示&#xff1a;教师数字人在直播授课场景中的眼神交互与手势模拟 1. 引言&#xff1a;当数字人老师走进直播间 想象一下&#xff0c;你正在准备一场面向数千名学生的在线直播课。除了精心准备的课件和讲稿&#xff0c;你还需要一个能清晰传达知识、与…...

再次了解 AI Harness

这其实是一次 tenantId 联调 bug&#xff0c;暴露了 AI 项目最缺的不是模型&#xff0c;而是Harness前面没整理完的关于Harness Engineering 的文章&#xff0c;为啥整理这一篇是因为这让我意识到一个趋势正在形成&#xff1a;AI 开发正在从"写提示词"转向"构建…...

扩散模型对抗样本经典baselines

1. 流图&#xff1a;数据的河流 如果把传统的堆叠面积图想象成一块块整齐堆叠的积木&#xff0c;那么流图就像一条蜿蜒流淌的河流&#xff0c;河道的宽窄变化自然流畅&#xff0c;波峰波谷过渡平滑。 它特别适合展示多个类别数据随时间的变化趋势&#xff0c;尤其是当你想强调整…...

独立站建站成本全解析

独立站建站费用构成独立站的费用主要分为域名注册、主机托管、网站建设、支付接口、营销推广和日常维护等几个部分。每个部分的费用因需求不同而有较大差异。域名注册费用通常在每年10至100美元之间&#xff0c;取决于域名后缀和注册商。常见的.com域名价格在10至20美元/年&…...

PLC课程设计 - 基于智能立体4层停车库的设计

题目&#xff1a;PLC课程设计-基于智能立体4层停车库的设计 仿真软件博图18 资料包括&#xff1a;博图软件仿真流程图开题ppt课设报告参考 实现功能&#xff1a; 立体车库&#xff0c;有四层&#xff0c;可以实现对应位置的存车及取车功能 当存车的时候&#xff0c;首先需要判断…...

从85分到95+:复盘我在科大奥锐虚拟仿真实验平台踩过的那些‘坑’

从85分到95&#xff1a;科大奥锐虚拟仿真实验平台的实战避坑指南 第一次接触科大奥锐虚拟仿真实验平台时&#xff0c;我和大多数同学一样&#xff0c;以为这不过是传统实验的电子版。直到连续三次实验分数卡在85分上下&#xff0c;才意识到这个平台对操作细节的严苛程度远超预期…...