2025最新款Electron38+Vite7+Vue3+ElementPlus电脑端后台系统Exe

历时两周高强度研发,新款跨平台electron38+vite7中后台通用管理系统完结啦~

使用技术

  • 开发工具:vscode
  • 跨平台框架:electron^38.1.2
  • 前端框架技术:vite^7.1.7+vue^3.5.21+vue-router^4.5.1
  • UI组件库:element-plus^2.11.3
  • 状态插件:pinia^3.0.3
  • 国际化方案:vue-i18n^11.1.12
  • 图表组件:echarts^6.0.0
  • markdown编辑器:md-editor-v3^6.0.1
  • 模拟数据:mockjs^1.1.0
  • 打包工具:electron-builder^24.13.3
  • electron+vite整合插件:vite-plugin-electron^0.29.0

项目功能特征

  1. 基于最新技术栈Electron38、Vite7、Vue3 setup、Pinia3、ElementPlus、Vue-I18n、Echarts
  2. 支持中英文/繁体三种国际化语言
  3. 支持动态权限路由、面包屑导航、快捷标签栏缓存路由
  4. electron38封装高复用多窗口管理
  5. 内置4种通用布局模板、自由变换风格
  6. 整合常用的表格、表单、列表、图表、编辑器、错误处理等业务模块

项目框架目录

使用最新跨平台技术Electron38整合Vite7搭建项目模板。

electron多窗口进程配置

ts 复制代码
/**
 * electron主进程配置
 * @author andy
 */

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'] = true

const 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()
})

前端页面入口配置main.js

ts 复制代码
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')
})

通用布局结构

如上图:内置了4种常用的通用布局模板。也可以自己定制需要的模板。

ts 复制代码
<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>

经典布局模板

ts 复制代码
<script setup>
  import { appState } from '@/pinia/modules/app'

  import Toolbar from '@/layouts/components/Toolbar.vue'
  import Sidebar from '@/layouts/components/sidebar/index.vue'
  import Menus from '@/layouts/components/menus/index.vue'
  import Breadcrumb from '@/layouts/components/Breadcrumb.vue'
  import Tabview from '@/layouts/components/Tabview.vue'
  import Main from '@/layouts/components/Main.vue'

  const appstate = appState()
</script>

<template>
  <div class="vuadmin__layout flexbox flex-col">
    <Toolbar />

    <div class="vuadmin__layout-body flex1 flexbox">
      <!-- 侧边栏 -->
      <div class="vuadmin__layout-sidebar">
        <Sidebar />
      </div>

      <!-- 菜单栏 -->
      <div class="vuadmin__layout-menus" :class="{'hidden': appstate.config.collapsed}">
        <el-scrollbar>
          <Menus :rootRouteEnable="false" />
        </el-scrollbar>
      </div>

      <!-- 右侧主内容区 -->
      <div class="vuadmin__layout-main flex1 flexbox flex-col">
        <!-- 面包屑导航 -->
        <Breadcrumb v-if="appstate.config.breadcrumb" />

        <!-- 标签页 -->
        <Tabview v-if="appstate.config.tabview" />

        <!-- 内容区 -->
        <Main />
      </div>
    </div>
  </div>
</template>

vue3+electron自定义无边框窗口导航条

ts 复制代码
<script setup>
  import { ref, markRaw } from 'vue'
  import { ElMessageBox } from 'element-plus'
  import { QuestionFilled, SwitchButton } from '@element-plus/icons-vue'
  import { isTrue } from '@/utils'
  import { authState } from '@/pinia/modules/auth'
  import { winSet } from '@/windows/actions'

  const authstate = authState()

  const props = defineProps({
    color: String,
    // 窗口是否可最小化
    minimizable: {type: [Boolean, String], default: true},
    // 窗口是否可最大化
    maximizable: {type: [Boolean, String], default: true},
    // 窗口是否可关闭
    closable: {type: [Boolean, String], default: true},
    // 层级
    zIndex: {type: [Number, String], default: 2024},
  })

  const hasMaximized = ref(false)
  
  // 初始监听窗口是否最大化
  window.electron.invoke('win-isMaximized').then(res => {
    hasMaximized.value = res
  })
  // 实时监听窗口是否最大化
  window.electron.on('win-maximized', (e, data) => {
    hasMaximized.value = data
  })

  // 最小化
  const handleWinMin = () => {
    // winSet('minimize', window.config.id)
    window.electron.invoke('win-min')
  }
  // 最大化/还原
  const handleWinToggle = () => {
    // winSet('max2min', window.config.id)
    window.electron.invoke('win-toggle').then(res => {
      hasMaximized.value = res
    })
  }
  // 关闭
  const handleWinClose = () => {
    if(window.config.isMajor) {
      ElMessageBox.confirm('是否最小化到系统托盘,不退出应用程序?', '', {
        type: 'warning',
        icon: markRaw(QuestionFilled),
        confirmButtonText: '退出应用',
        cancelButtonText: '最小化到托盘',
        customStyle: {'borderRadius': '8px'},
        roundButton: true,
        distinguishCancelAndClose: true,
      }).then(() => {
        authstate.logout()
        winSet('close')
      }).catch((action) => {
        if(action === 'cancel') {
          setTimeout(() => {
            winSet('hide', window.config.id)
          }, 250)
        }
      })
    }else {
      winSet('close', window.config.id)
    }
  }
</script>

<template>
  <div class="ev__winbtns vu__drag" :style="{'z-index': zIndex}">
    <div class="ev__winbtns-actions vu__undrag" :style="{'color': color}">
      <a v-if="isTrue(minimizable)" class="wbtn min" title="最小化" @click="handleWinMin"><i class="wicon iconfont elec-icon-min"></i></a>
      <a v-if="isTrue(maximizable)" class="wbtn toggle" :title="hasMaximized ? '向下还原' : '最大化'" @click="handleWinToggle">
        <i class="wicon iconfont" :class="hasMaximized ? 'elec-icon-restore' : 'elec-icon-max'"></i>
      </a>
      <a v-if="isTrue(closable)" class="wbtn close" title="关闭" @click="handleWinClose"><i class="wicon iconfont elec-icon-quit"></i></a>
    </div>
  </div>
</template>

国际化配置

如上图:提供了中英文/繁体三种常用的多语言配置。

ts 复制代码
/**
 * 国际化配置
 * @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 || langVal
  appstate.setLang(lang)

  const i18n = createI18n({
    legacy: false,
    locale: lang,
    messages: {
      'en': enUS,
      'zh-CN': zhCN,
      'zh-TW': zhTW
    }
  })
  
  app.use(i18n)
}

vue3+electron路由动态tabview标签

ts 复制代码
<template>
  <div class="vu__tabview">
    <el-tabs
      v-model="activeTab"
      class="vu__tabview-tabs"
      @tab-change="changeTabs"
      @tab-remove="removeTab"
    >
    <el-tab-pane
      v-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>
ts 复制代码
<script setup>
  import { computed } from 'vue'
  import { Fold, Expand } from '@element-plus/icons-vue'
  import { appState } from '@/pinia/modules/app'

  import { useRoutes } from '@/hooks/useRoutes'

  const props = defineProps({
    // 是否显示展开/收缩
    collapseEnable: { type: Boolean, default: true },
  })

  const appstate = appState()
  const { getMatchRoute } = useRoutes()

  const matchRoute = computed(() => getMatchRoute())

  const handleCollapse = () => {
    appstate.config.collapsed = !appstate.config.collapsed
  }
</script>

<template>
  <div class="vu__breadcrumb flexbox">
    <el-icon v-if="collapseEnable" :title="appstate.config.collapsed ? '展开' : '收缩'" @click="handleCollapse">
      <Expand v-if="appstate.config.collapsed" />
      <Fold v-else />
    </el-icon>
    <el-breadcrumb separator="/">
      <el-breadcrumb-item v-for="(item, index) in matchRoute" :key="index">
        <router-link v-if="item.path" :to="item.path">{{$t(item?.meta?.title)}}</router-link>
        <template v-else>{{$t(item?.meta?.title)}}</template>
      </el-breadcrumb-item>
    </el-breadcrumb>
  </div>
</template>

基于electron38+vite7+vue3 setup+elementPlus电脑端仿微信/QQ聊天软件

最新版Vite7+Vue3+Pinia3+ArcoDesign网页版webos后台管理系统

基于uniapp+vue3+uvue仿抖音app短视频+聊天+直播app系统

Flutter3.x深度融合短视频+直播+聊天app实例

基于uniapp+vue3+deepseek+markdown搭建app版流式输出AI模板

vue3.5+deepseek+arco+markdown搭建web版流式输出AI模板

unios-admin手机版后台|uniapp+vue3全端admin管理系统

基于flutter3.32+window_manager仿macOS/Wins风格桌面os系统

flutter3.27+bitsdojo_window电脑端仿微信Exe应用

自研tauri2.0+vite6.x+vue3+rust+arco-design桌面版os管理系统Tauri2-ViteOS

基于uni-app+vue3+uvui跨三端仿微信app聊天模板

自研tauri2.0+vite5+vue3+element-plus电脑版exe聊天系统Vue3-Tauri2Chat

相关推荐
恋猫de小郭30 分钟前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端