🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付

2025最新款Electron38+Vite7+Vue3+ElementPlus電腦端後台系統Exe

image

歷時兩周高強度研發,新款跨平台 electron38+vite7 中後台通用管理系統完結啦~

003360截圖20250927231943953.png

008360截圖20250927234849127.png

使用技術

  • 開發工具: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

p5.gif

p3.gif

專案功能特徵

  1. 基於最新技術棧Electron38、Vite7、Vue3 setup、Pinia3、ElementPlus、Vue-I18n、Echarts
  2. 支援中英文/繁體三種國際化語言
  3. 支援動態權限路由、麵包屑導航、快捷標籤欄快取路由
  4. electron38封裝高重用多窗口管理
  5. 內建4種通用佈局模板、自如變換風格
  6. 整合常用的表格、表單、列表、圖表、編輯器、錯誤處理等業務模組

p4.gif

專案框架目錄

使用最新跨平台技術Electron38整合Vite7搭建專案模板。

360截圖20250927220018261.png

electron多窗口進程配置

/**
 * 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

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')
})

360截圖20250927220018271.png

p1.gif

360截圖20250927223442641.png

360截圖20250927223731164.png

360截圖20250927224511797.png

360截圖20250927231630898.png

通用佈局結構

f421c9b8f945563a663c8bc876bb3b7e_1289798-20250928084102365-861716096.png

如上圖:內建了4種常用的通用佈局模板。也可以自己定制需要的模板。

ac7f37e36c4a7d36e67f2c83fd5a35a4_1289798-20250928084157925-768517553.png

<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>

經典佈局模板

<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>

360截圖20250927225006085.png

008360截圖20250927234536887.png

008360截圖20250927234822853.png

008360截圖20250927234849127.png

009360截圖20250927235108716.png

010360截圖20250927235449672.png

011360截圖20250927235755916.png

014360截圖20250928000540946.png

016360截圖20250928000806441.png

017360截圖20250928000946641.png

018360截圖20250928001133978.png

019360截圖20250928001325329.png

020360截圖20250928001553936.png

025360截圖20250928001742729.png

026360截圖20250928001858352.png

027360截圖20250928001946641.png

vue3+electron自定義無邊框窗口導航條

image.png

7e8265c4826bc9e9445940ede453a6dd_1289798-20250928090240630-1537934143.png

<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>

國際化配置

f53f8a63386532af39f60f7a5f2db6b9_1289798-20250928090551822-1074723762.png

如上圖:提供了中英文/繁體三種常用的多語言配置。

e08c24fe168cf65b4cede8595a215040_1289798-20250928090902923-1518758104.png

/**
 * 國際化配置
 * 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標籤

0bcaa8cbd145d8e0dc801a44d7665f4d_1289798-20250928092159118-295510264.png


原文出處:https://juejin.cn/post/7555690975866044431


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝19   💬9   ❤️5
723
🥈
我愛JS
📝4   💬13   ❤️7
243
🥉
AppleLily
📝1   💬3   ❤️1
69
#4
御魂
💬1  
3
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付