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

Electron31-ViteAdmin桌面端后台|vite5.x+electron31+element-plus管理系统Exe

原创自研Vue3+Electron31+ElementPlus桌面端轻量级后台管理Exe系统。

基于最新前端技术栈Vite5.x、Vue3、Electron31、ElementPlus、Vue-I18n、Echarts实战开发桌面端高颜值后台管理模板。内置4种布局模板,支持i18n国际化、动态权限路由,实现了表格、表单、图表、列表、编辑器等常见的业务模块。

在这里插入图片描述
在这里插入图片描述
electron-viteadmin封装了多窗口管理,支持同时开启多个窗体。

在这里插入图片描述

运用技术

  • 编辑器:vscode
  • 框架技术:vite5.3+vue3.4+vue-router^4.4
  • 跨平台框架:electron^31.3
  • 组件库:element-plus^2.7.8
  • 状态管理:pinia^2.2.0
  • 国际化方案:vue-i18n@9
  • 图表组件:echarts^5.5.1
  • markdown编辑器:md-editor-v3^4.18.0
  • 模拟数据:mockjs^1.1.0
  • 打包工具:electron-builder^24.13.3

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

项目框架结构

electron-vue3admin 整合vite5+electron技术,采用vue3 setup语法编码。

在这里插入图片描述
在这里插入图片描述
目前electron-vue3admin已经同步到我的原创作品集,欢迎下载使用。
自研Electron31+Vue3+ElementPlus桌面端后台管理系统

在这里插入图片描述

特性

  1. 最新前端技术栈electron31、vite5、vue3、elementPlus、vue-i18n、echarts
  2. 支持中英文/繁体国际化解决方案
  3. 支持动态权限路由、多页签缓存路由
  4. 封装多窗口管理器,内置4种通用布局模板、自由切换风格
  5. 整合通用的表格、表单、列表、图表、编辑器、错误处理等模块
  6. 高颜值UI界面、轻量级模块化、高定制性

在这里插入图片描述

electron主进程配置

import { app, BrowserWindow } from 'electron'import { WindowManager } from '../src/windows/index.js'// 忽略安全警告提示 Electron Security Warning (Insecure Content-Security-Policy)
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = trueconst createWindow = () => {let win = new WindowManager()win.create({isMajor: true})// 系统托盘管理win.trayManager()// 监听ipcMain事件win.ipcManager()
}app.whenReady().then(() => {createWindow()app.on('activate', () => {if(BrowserWindow.getAllWindows().length === 0) createWindow()})
})app.on('window-all-closed', () => {if(process.platform !== 'darwin') app.quit()
})

vue3入口文件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) {console.log('窗口参数:', config)console.log('窗口id:', config?.id)// 全局存储窗口配置window.config = config}// 初始化app应用实例createApp(App).use(Router).use(Pinia).use(Plugins).mount('#app')
})

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

electron31-admin布局模板

在这里插入图片描述
提供了4种常用的布局模板。也可以根据需求定制化模板。

在这里插入图片描述

/*** 通用布局模板* @author Andy Q:282310962
*/<script setup>import { appState } from '@/pinia/modules/app'// 引入布局模板import Classic from './template/classic/index.vue'import Columns from './template/columns/index.vue'import Vertical from './template/vertical/index.vue'import Horizontal from './template/horizontal/index.vue'const appstate = appState()const LayoutMap = {'classic': Classic,'columns': Columns,'vertical': Vertical,'horizontal': Horizontal}
</script><template><div class="vuadmin__container" :style="{'--themeSkin': appstate.config.skin}"><component :is="LayoutMap[appstate.config.layout]" /></div>
</template>

electron+vue3国际化解决方案

在这里插入图片描述

采用vue-i18n国际化方案,支持中文/英文/繁体三种语言。

在这里插入图片描述

/*** 国际化配置* @author YXY*/import { createI18n } from 'vue-i18n'
import { appState } from '@/pinia/modules/app'// 引入语言配置
import enUS from './en-US'
import zhCN from './zh-CN'
import zhTW from './zh-TW'// 默认语言
export const langVal = 'zh-CN'export default async (app) => {const appstate = appState()const lang = appstate.lang || langValappstate.setLang(lang)const i18n = createI18n({legacy: false,locale: lang,messages: {'en': enUS,'zh-CN': zhCN,'zh-TW': zhTW}})app.use(i18n)
}

electron+vue3封装图表

在这里插入图片描述

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

/*** 动态图表Hook*/import { onMounted, onBeforeUnmount, ref } from 'vue'
import * as echarts from 'echarts'
import elementResizeDetectorMaker from 'element-resize-detector'export function useEcharts(el, options) {let chartEllet chartRef = ref(null)let erd = elementResizeDetectorMaker()const resizeHandle = () => {chartEl && chartEl.resize()}onMounted(() => {if(el?.value) {chartEl = echarts.init(el.value)chartEl.setOption(options)chartRef.value = chartEl}erd.listenTo(el.value, resizeHandle)})onBeforeUnmount(() => {chartEl.dispose()erd.removeListener(el.value, resizeHandle)})return chartRef
}

vue3封装路由菜单

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
内置的4种布局模板,提供了4种不同形式的路由菜单。

<Menus :rootRouteEnable="false" /><Menus rootRouteEnable :dark="true" /><Menus mode="horizontal" :dark="true" />
<script setup>import { ref, computed } from 'vue'import { isObject, isArray, isImg } from '@/utils'import { appState } from '@/pinia/modules/app'import { useRoutes } from '@/hooks/useRoutes'const props = defineProps({// 菜单模式(vertical|horizontal)mode: { type: String, default: 'vertical' },// 是否开启一级路由菜单rootRouteEnable: { type: Boolean, default: true },// 是否暗黑模式dark: { type: Boolean }})import Submenu from './submenu.vue'// 引入主路由表import routes from '@/router/modules/main.js'const appstate = appState()const { route, getActiveRoute, getCurrentRootRoute, getTreeRoutes } = useRoutes()const activeRoute = computed(() => getActiveRoute(route))const rootRoute = computed(() => getCurrentRootRoute(route))const treeRoutes = computed(() => getTreeRoutes(routes))const filterRoutes = computed(() => {if(props.rootRouteEnable) {return treeRoutes.value}// 过滤一级路由菜单return treeRoutes.value.find(item => item.path === rootRoute.value && item.children)?.children})
</script><template><div class="vu__menubar" :class="{'is-dark': dark, 'is-collapsed': mode == 'vertical' && appstate.config.collapsed}"><el-menu class="vu__menus" :default-active="activeRoute" :mode="mode" :collapse="appstate.config.collapsed"><Submenuv-for="route in filterRoutes":key="route.path":item="route":rootRoute="rootRoute":rootRouteEnable="rootRouteEnable"/></el-menu></div>
</template>

vue3自定义多标签tab路由

在这里插入图片描述

<template><div class="vu__tabview"><el-tabsv-model="activeTab"class="vu__tabview-tabs"@tab-change="changeTabs"@tab-remove="removeTab"><el-tab-panev-for="(item, index) in tabList":key="index":name="item.path":closable="!item?.meta?.isAffix"><template #label><el-dropdown ref="dropdownRef" trigger="contextmenu" :id="item.path" @visible-change="handleDropdownChange($event, item.path)" @command="handleDropdownCommand($event, item)"><span class="vu__tabview-tabs__label"><span>{{$t(item?.meta?.title)}}</span></span><template #dropdown><el-dropdown-menu><el-dropdown-item command="refresh" :icon="Refresh">{{$t('tabview__contextmenu-refresh')}}</el-dropdown-item><el-dropdown-item command="close" :icon="Close" :disabled="item.meta.isAffix">{{$t('tabview__contextmenu-close')}}</el-dropdown-item><el-dropdown-item command="closeOther" :icon="Switch">{{$t('tabview__contextmenu-closeother')}}</el-dropdown-item><el-dropdown-item command="closeLeft" :icon="DArrowLeft">{{$t('tabview__contextmenu-closeleft')}}</el-dropdown-item><el-dropdown-item command="closeRight" :icon="DArrowRight">{{$t('tabview__contextmenu-closeright')}}</el-dropdown-item><el-dropdown-item command="closeAll" :icon="CircleCloseFilled">{{$t('tabview__contextmenu-closeall')}}</el-dropdown-item></el-dropdown-menu></template></el-dropdown></template></el-tab-pane></el-tabs></div>
</template><script setup>import { onMounted, ref, computed, watch, nextTick } from 'vue'import { useRouter, useRoute } from 'vue-router'import { useI18n } from 'vue-i18n'import { Refresh, Close, Switch, DArrowLeft, DArrowRight, CircleCloseFilled } from '@element-plus/icons-vue'import { isObject, isImg } from '@/utils'import { useLink } from '@/hooks/useLink'import { appState } from '@/pinia/modules/app'const router = useRouter()const route = useRoute()const { jump } = useLink()const { locale } = useI18n()let { config: { keepAlive, tabRoutes, cacheRoutes }, updateConfig } = appState()const dropdownRef = ref()const activeTab = ref(route.path)const tabList = ref(tabRoutes)// 新增选项卡const addTab = () => {const index = tabList.value.findIndex(item => item?.path === activeTab.value)if(index == -1) {tabList.value.push({path: route?.path,name: route?.name,meta: {...route?.meta,}})}updateConfig('tabRoutes', tabList.value)updateCacheRoutes()}// 删除选项卡const removeTab = (path) => {const index = tabList.value.findIndex(item => item?.path === path)if(index > -1) {tabList.value.splice(index, 1)updateTabs(tabList.value)}}// 删除左侧选项卡const removeLeftTab = (path) => {const index = tabList.value.findIndex(item => item?.path === path)if(index > -1) {tabList.value = tabList.value.filter((item, i) => item?.meta?.isAffix || i >= index)updateTabs(tabList.value)}}// 删除右侧选项卡const removeRightTab = (path) => {const index = tabList.value.findIndex(item => item?.path === path)if(index > -1) {tabList.value = tabList.value.filter((item, i) => item?.meta?.isAffix || i <= index)updateTabs(tabList.value)}}// 删除其它选项卡const removeOtherTab = (path) => {tabList.value = tabList.value.filter(item => item?.meta?.isAffix || item?.path === path)updateTabs(tabList.value)}// 删除全部const removeAllTab = (path) => {tabList.value = tabList.value.filter(item => item?.meta?.isAffix)updateTabs(tabList.value)}// 更新选项卡const updateTabs = (tabs) => {updateConfig('tabRoutes', tabs)updateCacheRoutes()const nextTab = tabs[tabs.length + 1] || tabs[tabs.length - 1]if(!nextTab) returnjump(nextTab?.path)}// 更新keep-alive缓存const updateCacheRoutes = () => {let caches = tabList.value.filter(item => keepAlive || item?.meta?.isKeepAlive).map(item => item.name)updateConfig('cacheRoutes', caches)}// 清空keep-alive缓存const clearCacheRoutes = () => {updateConfig('cacheRoutes', [])}// 点击选项卡const changeTabs = (path) => {jump(path)}// 右键菜单更新const handleDropdownChange = (visible, name) => {// 控制每次只显示一个右键菜单if(!visible) returndropdownRef.value.forEach(item => {if(item.id === name) returnitem.handleClose()})}// 右键菜单命令const handleDropdownCommand = (cmd, item) => {const path = item?.pathswitch(cmd) {case 'refresh':router.go(0)breakcase 'close':removeTab(path)breakcase 'closeLeft':removeLeftTab(path)breakcase 'closeRight':removeRightTab(path)breakcase 'closeOther':removeOtherTab(path)breakcase 'closeAll':removeAllTab()break}}watch(() => route.path, () => {activeTab.value = route.pathaddTab()}, {immediate: true})
</script>

以上就是Electron31+vue3 setup+elementPlus开发桌面端中后台管理系统的一些知识分享,整个项目涉及到的知识点还是蛮多的,限于篇幅就先分享到这里。

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

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

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

在这里插入图片描述

http://www.lryc.cn/news/428279.html

相关文章:

  • 鸿蒙HarmonyOS实战:创建NDK工程、毕昇编译器
  • 网络安全-防火墙初步认识。
  • golang channel什么情况main会deadlock?主协程是什么?
  • Redis之快速入门
  • mac 安装Arthas
  • 创客匠人老蒋:流量是个伪命题,做好这件事是打造IP最好避坑方式
  • 销售预测数据挖掘实战V2.0
  • 【K8s】Java项目部署时为什么要用k8s?
  • 【Python】AttributeError: module ‘PIL.Image‘ has no attribute ‘ANTIALIAS‘
  • SQL注入(cookie、base64、dnslog外带、搜索型注入)
  • GPT-4:揭秘人工智能新纪元
  • Taro 框架 React Native 开发
  • 学会平衡日常编码工作与提升学习
  • navicate premium16破解
  • Kafka运行机制(一):Kafka集群启动,controller选举,生产消费流程
  • 安徽医科大学:利用UKB数据库和孟德尔随机化,研究发表更轻松!
  • Ubuntu安装gdb出现错误的问题解决,DNS解析错误导致的安装失败
  • 【Redis】解析Redisson 限流器源码
  • docker-harbor 私有仓库部署和管理
  • 机器学习笔记二-回归
  • 判断http链接中文件是否存在
  • Flink CDC (session模式)
  • 下载ISO镜像的方法 Debian、Red Hat 、CentOS、Ubuntu、Kali Linux
  • 想学接口测试,不知道那个工具适合?
  • 干货分享 | TSMaster—RP1210模块使用指南
  • 一步解决Ubuntu中无法使用git clone的问题
  • c++的时间复杂度
  • PDF转图片 JAVA
  • 树莓派5 笔记26:ollama大型语言模型_中文输入法_Python_espeak文字转语音
  • 【kubernetes】k8s安全机制