Electron35-DeepSeek桌面端AI系统|vue3.5+electron+arco客户端ai模板
2025跨平台ai实战electron35+vite6+arco仿DeepSeek/豆包ai流式打字聊天助手。
electron-deepseek-chat:实战ai大模型对话,基于vue3.5+electron35接入DeepSeek-V3聊天对话模板,支持多窗口、流式stream输出、暗黑+亮色主题、代码高亮、上下文多轮对话、本地存储会话等功能。

使用技术
- 编码工具:VScode
- 技术框架:vite^6.2.0+vue^3.5.13+vue-router^4.5.0
- 大模型ai框架:DeepSeek-V3-0324 + OpenAI
- 跨平台框架:electron^35.1.2
- 组件库:arco-design^2.57.0 (字节桌面端组件库)
- 状态插件:pinia^3.0.1
- 会话缓存:pinia-plugin-persistedstate^4.2.0
- 高亮插件:highlight.js^11.11.1
- markdown解析:markdown-it


️项目特色
- 基于跨平台Electron35框架,接入DeepSeek-V3,性能更丝滑
- 支持各种代码高亮效果、易于展示分享代码片段
- 支持上下文多轮对话、提示词生成图片及预览功能
- 支持多窗口、亮色+暗黑主题
- 支持新窗口打开会话里面的链接
- 采用arco-design组件库,风格一致性

项目框架结构
使用 electron35+vite6 搭建项目模板,接入 deepseek-v3 聊天模型,采用vue3 setup语法编码。

Electron35-DeepSeek桌面端AI项目已经同步到我的原创作品铺,感谢大家的支持~
.env配置文件
# 项目名称
VITE_APPNAME = 'Electron35-DeepSeek' # 运行端口
VITE_PORT = 3003 # 是否加载调试工具devtools
VITE_DEVTOOLS = true # 是否打开调试工具devtools
VITE_OPEN_DEVTOOLS = true # 是否删除生产环境console
VITE_DROP_CONSOLE = true # DeepSeek API配置
VITE_DEEPSEEK_API_KEY = 替换为你的 API Key
VITE_DEEPSEEK_BASE_URL = https://api.deepseek.com
渲染进程入口main.js
import { createApp } from 'vue'
import './style.scss'
import App from './App.vue'
import { launchApp } from '@/windows/actions'
// 引入路由/状态配置
import Router from './router'
import Pinia from './pinia'
// 引入插件配置
import Plugins from './plugins'
launchApp().then(config => {
if(config) {// 全局存储窗口配置
window.config = config
}
// 初始化app实例
createApp(App)
.use(Router)
.use(Pinia)
.use(Plugins)
.mount('#app')
})


项目布局模板

项目整体分为顶部自定义导航条+侧边栏+主体对话区三个大模块。

<script setup>
import Titlebar from '@/layouts/components/titlebar/index.vue'
import Sidebar from '@/layouts/components/sidebar/index.vue'
</script> <template>
<div class="vu__container">
<div class="vu__layout flexbox flex-col">
<!-- 导航栏 -->
<Titlebar /> <div class="vu__layout-body flex1 flexbox">
<!-- 侧边 -->
<Sidebar /> <!-- 对话区 -->
<div class="vu__layout-main flex1">
<router-view v-slot="{ Component, route }">
<keep-alive>
<component :is="Component" :key="route.path" />
</keep-alive>
</router-view>
</div>
</div>
</div>
</div>
</template>
当历史对话超过一定高度,会如下图箭头所示,出现滚动条显示。


路由配置

import { createRouter, createWebHashHistory } from 'vue-router'
import { authState } from '@/pinia/modules/auth'
import Layout from '@/layouts/index.vue'
import { loginWindow } from '@/windows/actions'
// 批量导入路由
const modules = import.meta.glob('./modules/*.js', { eager: true })
const patchRouters = Object.keys(modules).map(key => modules[key].default).flat()
/**
* meta配置
* @param meta.requireAuth 需登录验证页面
*/
const routes = [
...patchRouters,
// 错误模块
{
path: '/:pathMatch(.*)*',
redirect: '/404',
component: Layout,
meta: {
title: '404 error',
},
children: [
{
path: '404',
component: () => import('@/views/error/404.vue'),
}
]
},
]
const router = createRouter({
history: createWebHashHistory(),
routes,
})
// 全局路由钩子拦截
router.beforeEach((to, from) => {
const authstate = authState()
// 登录验证
if(to?.meta?.requireAuth && !authstate.authorization) {
// console.log('你还未登录!')
loginWindow()
}
})
router.afterEach(() => {
// ...
})
router.onError(error => {
console.warn('[Router Error]', error)
})
export default router

















AI对话编辑框


编辑框封装在components目录下ChatEditor.vue文件。

<template>
<div class="v3ai__footbar flexbox flex-col">
<!-- 技能栏 -->
<div v-if="skillbar" class="v3ai__skills flexbox flex-alignc">
...
</div>
<!-- 编辑栏 -->
<div class="v3ai__inputbox flexbox flex-col">
<div class="v3ai__editor flexbox">
...
</div>
<!-- 操作栏 -->
<div class="v3ai__tools flexbox flex-alignc">
<div class="option flex1 flexbox">
<div class="btn" :class="{'active': isDeep}" @click="isDeep =! isDeep"><i class="iconfont ai-deepthink"></i> 深度思考 <span class="fs-12">(R1)</span></div>
<div class="btn" :class="{'active': isNetwork}" @click="isNetwork =! isNetwork"><i class="iconfont ai-network"></i> 联网</div>
</div>
<a-dropdown trigger="hover" :show-arrow="false" position="lb" :content-style="{'min-width': '250px'}">
<a-button shape="circle"><icon-attachment size="18" /></a-button>
<template #content>
<a-dgroup>
<template #title><div style="margin-bottom: 5px;">从网盘添加</div></template>
<a-doption value="wx"><icon-more /> 选择网盘文件</a-doption>
</a-dgroup>
<a-dgroup>
<template #title><div style="margin-bottom: 5px;">从本地添加</div></template>
<a-doption value="wx"><icon-apps /> 上传文件</a-doption>
<a-dsubmenu trigger="hover" position="rb" :popup-translate="[8, 8]" value="option-1" :content-style="{'min-width': '125px'}">
<template #default><icon-apps /> 上传代码</template>
<template #content>
<a-doption value="pyq"><icon-apps /> 代码文件</a-doption>
<a-doption value="qq"><icon-apps /> 代码文件夹</a-doption>
<a-doption value="qq"><icon-apps /> GitHub仓库</a-doption>
</template>
</a-dsubmenu>
</a-dgroup>
</template>
</a-dropdown>
<a-tooltip content="截图提问" position="top" mini>
<a-button shape="circle"><icon-scissor size="18" @click="handleCut" /></a-button>
</a-tooltip>
<a-dropdown :show-arrow="false" position="top" :popup-translate="[-10, -5]" :content-style="{'min-width': '160px'}">
<a-button shape="circle"><icon-plus size="18" /></a-button>
<template #content>
<a-doption value="image"><icon-file-image /> 图片</a-doption>
<a-doption value="file"><icon-file /> 本地文件</a-doption>
<a-doption value="pdf"><icon-file-pdf /> PDF文档分析</a-doption>
<a-doption value="page"><icon-cloud /> 网页总结</a-doption>
</template>
</a-dropdown>
<a-divider direction="vertical" style="margin: 0 7px;" />
<a-button class="submit" type="primary" shape="circle" :disabled="!editorText?.trim() || sessionstate.loading" @click="handleSubmit">
<icon-arrow-up v-if="!sessionstate.loading" size="20" />
<icon-loading v-else size="18" />
</a-button>
</div>
</div>
</div>
</template>
Electron35接入DeepSeek-V3聊天模型
实现一个正常非流式输出。
const completion = await openai.chat.completions.create({
// 单一会话
messages: [ {role: 'user', content: editorValue} ],
// 多轮会话
// messages: props.multiConversation ? historySession.value : [{role: 'user', content: editorValue}],
model: 'deepseek-chat',
stream: false, // 非流式输出
max_tokens: 8192, // 限制一次请求中模型生成 completion 的最大 token 数(默认使用 4096)
temperature: 0.4, // 严谨采样 越低越严谨(默认1)
})
// 一次性返回非流式内容
console.log(completion.choices[0].message.content)
通过for循环stream分片返回,实现流式打字输出效果。
// 使用数组存储chunk内容,提高拼接效率
let chunks = []
let lastUpdate = 0 // 处理流式输出
for await (const chunk of completion) {
const content = chunk.choices[0]?.delta?.content || ''
if(content) {
chunks.push(content)
// 限制更新频率:每100ms最多更新一次
const now = Date.now()
if (now - lastUpdate > 100) {
sessionstate.updateSession(botKey, {content: chunks.join('')})
lastUpdate = now
// 滚动最底部
if (sessionstate.reachBottom) {
props.scrollBottom()
}
}
}
if(chunk.choices[0]?.finish_reason === 'stop') {
sessionstate.loading = false
// 确保最终内容完整更新
sessionstate.updateSession(botKey, {content: chunks.join(''), loading: false})
if (sessionstate.reachBottom) {
props.scrollBottom()
}
}
}
综上就是Electron35+Vue3.5+DeepSeek开发客户端ai流式对话的一些知识分享,感谢大家的阅读与支持!
附上几个最新实战项目
Vue3-DeepSeek-Chat流式AI对话|vite6+vant4+deepseek智能ai聊天助手
vue3-webseek网页版AI问答|Vite6+DeepSeek+Arco流式ai聊天打字效果
Electron32-ViteOS桌面版os系统|vue3+electron+arco客户端OS管理模板
uniapp+vue3酒店预订|vite5+uniapp预约订房系统模板(h5+小程序+App端)
flutter3-dymall仿抖音直播商城|Flutter3.27短视频+直播+聊天App实例
Vite5+Electron聊天室|electron31跨平台仿微信EXE客户端|vue3聊天程序

Electron35-DeepSeek桌面端AI系统|vue3.5+electron+arco客户端ai模板的更多相关文章
- [资源共享]C#+AE构建GIS桌面端应用系统框架-全代码
转自:http://www.cnblogs.com/gispeng/archive/2008/10/06/1304534.html [资源共享]C#+AE构建GIS桌面端应用系统框架-全代码 ( ...
- AI测试101:测试AI系统的实用技巧&ML和AI自动化工具
基于人工智能的系统,也称为神经网络(NN Neural Networks),和其他应用程序一样是 "系统",因此需要测试.本文将指导你测试AI和基于NN的系统,并理解相关概念. 测 ...
- vue3系列:vue3.0自定义全局弹层V3Layer|vue3.x pc桌面端弹窗组件
基于Vue3.0开发PC桌面端自定义对话框组件V3Layer. 前两天有分享一个vue3.0移动端弹出层组件,今天分享的是最新开发的vue3.0版pc端弹窗组件. V3Layer 一款使用vue3.0 ...
- Electron-Vue3-Vadmin后台系统|vite2+electron桌面端权限管理系统
基于vite2.x+electron12桌面端后台管理系统Vite2ElectronVAdmin. 继上一次分享vite2整合electron搭建后台框架,这次带来的是最新开发的跨桌面中后台权限管理系 ...
- ve-plus:基于 vue3.x 桌面端UI组件库|vue3组件库
VE-Plus 自研轻量级 vue3.js 桌面pc端UI组件库 经过一个多月的筹划及开发,今天给大家带来一款全新的Vue3桌面端UI组件库VEPlus.新增了35+常用的组件,采用vue3 setu ...
- Tauri-Vue3桌面端聊天室|tauri+vite3仿微信|tauri聊天程序EXE
基于tauri+vue3.js+vite3跨桌面端仿微信聊天实例TauriVue3Chat. tauri-chat 运用最新tauri+vue3+vite3+element-plus+v3layer等 ...
- 使用JS开发桌面端应用程序NW.js-1-Menu菜单的使用小记
前言 本文主要内容为nw.js官方文档中没有提到,而在实际入手开发过程中才碰到的问题以及经验的汇总. 详情请查看官方文档:http://docs.nwjs.io/en/latest/Reference ...
- python桌面端开发手记(序列化、压缩包、加密、图形界面GUI)
0x00 前段时间接到一个小项目是给某行业内部开发离线桌面端,业务流实现上总体分信息录入.加密导出.因为是win桌面端,所以老板说依托Access用VBA做,我据理力争了一下.之前就是用Acces ...
- 重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印
重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印 一.引言 桌面端系统经常需要对接各种硬件设备,比如扫描器.读卡器.打印机等. 这里介绍下桌面端 ...
- Flutter Windows 桌面端支持进入稳定版
Flutter 创建伊始,我们就致力于打造一个能够构建精美的.可高度定制的.并且可以编译为机器码的跨平台应用解决方案,以充分发挥设备底层硬件的全部图形渲染能力.今天,Flutter 对 Windows ...
随机推荐
- ctfshow--web14 sql注入利用``的清奇的绕过
输入c=3就会跳出来这个url 复制并访问,看这个页面应该是sql注入 有注释可看,看看他过滤了哪些东西 点击查看代码 if(preg_match('/information_schema\.tabl ...
- Typora+PicGo+Gitee图床
Typora+PicGo+Gitee图床 介绍 Typora:一个用于写文章的Markdown 编辑器,Typora 没有采用源代码和预览双栏显示的方式,而是采用所见即所得的编辑方式,实现了即时预览的 ...
- babel-loader 如何工作? 什么是babel-loader插件? babel-loader插件可以干什么? 如何制作一个babel-loader插件?
本文会介绍比较基本的编译知识和babel-loader运作原理 babel-loader 是什么? 作为老一派的打包工具, babel-loader 想必大家已经非常熟悉了.它长这样子 // webp ...
- OpenCvSharp 打开rtsp视频并录制mp4文件
public class OpenCvSharpUtils { private VideoCapture Capture; private VideoWriter VideoWriter; priva ...
- [Windows] 联发科秒开bl一键版(mtk)
声明 不是所有的联发科都可 天机 8000 8100 9000等不行 已知 天机820 天机1000 mtk G90t 天机800 可以 其余自己测试 除了新款均可 第一步 下载软件 (是个压缩包需要 ...
- AI与.NET技术实操系列(四):使用Semantic Kernel和DeepSeek构建AI应用
引言 在人工智能技术飞速发展的今天,大型语言模型(Large Language Models, LLMs)已成为智能应用开发的核心驱动力.从智能客服到自动化内容生成,LLMs的应用正在深刻改变我们的工 ...
- MSBuild属性
MSBuild 属性 MSBuild属性是键值对的集合,提前声明好这些属性之后,整个项目的生成都可以引用这些属性. 属性名不区分大小写. 属性都是写在 PropertyGroup 标签中. 1.声明属 ...
- [tldr] 使用ip.sb检查自己所在局域网的公网IP
使用ip a等一些命令行工具可以帮助我们检查自己的内网IP,但是,如何获取自己的在公网下的IP(即当前所在的局域网被分配的公网IP) 如果使用爬虫,这个IP也是很重要的.BAN IP就是这个IP ht ...
- java真是一门丑陋的语言,我都new Thread.run了然后你告诉我是在当前线程中运行
new Thread(x->{}).run(); 上方代码怎么看都应该是要开启新线程的,毕竟都已经new了.但是上方代码居然是在当前线程中运行!想要开启新线程得用.start()方法,如下: n ...
- css设置backgroud:url(),无效
react项目中,使用styled-components编写样式,给元素添加背景图不生效. background直接设置十六进制颜色或者颜色的英文名称都是可行的,但是使用url无作用,那就是url问题 ...