vite2-electron-admin 一套輕量級的中後臺系統解決方案。它整合了vite.js + electron12
開發實現。使用了最新的前端技術棧,包含了 i18n 國際化語言,動態權限路由,提供了多功能表格/表單
業務功能。css
electron-vite-admin 還支持新開多窗口,以以下換膚窗口爲例,前面已經有過相關分享文章,這裏就不詳細介紹。前端
import { createWin } from '@/windows/actions' // 換膚窗口 const handleOpenTheme = () => { createWin({ title: '主題換膚', route: '/skin', width: 750, height: 480, }) }
如上圖:爲了項目UI一致性,頂部導航欄採用了自定義組件實現,風格有些相似mac導航。vue
<template> <WinBar zIndex="1000"> <template #wbtn> <MsgMenu /> <Lang /> <a class="wbtn" title="換膚" @click="handleSkinWin"><i class="iconfont icon-huanfu"></i></a> <Setting /> <a class="wbtn" title="刷新" @click="handleRefresh"><i class="iconfont el-icon-refresh"></i></a> <a class="wbtn" :class="{'on': isAlwaysOnTop}" :title="isAlwaysOnTop ? '取消置頂' : '置頂'" @click="handleAlwaysTop"><i class="iconfont icon-ding"></i></a> <Avatar @logout="handleLogout" /> </template> </WinBar> </template>
至於具體的實現方式,這裏不做過多介紹了。以前有過一些相關分享文章。vue-router
/** * 渲染進程主入口 * @author XiaoYan */ import { createApp } from 'vue' import App from './App.vue' import Router from './router' import Store from './store' // 引入公共配置 import gPlugins from './plugins' import { winCfg, loadWin } from './windows/actions' loadWin().then(config => { winCfg.window = config createApp(App).use(Router).use(Store).use(gPlugins).mount('#app') })
/** * 公共組件/插件配置文件 * @author XiaoYan */ // 引入公共樣式 import "@/assets/fonts/iconfont.css" import "@/assets/css/common.scss" // 引入elementPlus組件庫 import ELPlus from "element-plus" // 引入國際化配置 import VueI18n, { elPlusLang, getLang } from './i18n' // 引入vue3自定義組件 import V3Layer from '@/components/v3layer' import V3Scroll from '@/components/v3scroll' // 引入公共組件模板 import WinBar from '@/components/winbar' import WinBtn from '@/components/winbar/winbtn.vue' import MacBtn from '@/components/winbar/macbtn.vue' import Icon from '@/components/Icon' import Utils from '@/utils' import ElUtil from './elUtil' const gPlugins = (app) => { app.use(ELPlus, { size: 'small', locale: elPlusLang[getLang()] }) app.use(VueI18n) app.use(V3Layer) app.use(V3Scroll) // 註冊公共組件 app.component('WinBar', WinBar) app.component('WinBtn', WinBtn) app.component('MacBtn', MacBtn) app.component('Icon', Icon) // 注入全局依賴 app.provide('utils', Utils) app.provide('elUtil', ElUtil) }
新建一個i18n.js用來引入國際化語言配置。vuex
/** * 國際化配置 VueI18n util * @author XiaoYan Q:282310962 */ import { createI18n } from "vue-i18n" import Storage from "@/utils/storage" // 默認值 export const langKey = 'lang' export const langVal = 'zh-CN' /* elementPlus國際化配置 */ import enUS from "element-plus/lib/locale/lang/en" import zhCN from "element-plus/lib/locale/lang/zh-cn" import zhTW from "element-plus/lib/locale/lang/zh-tw" export const elPlusLang = { 'en-US': enUS, 'zh-CN': zhCN, 'zh-TW': zhTW, } /* 初始化多語言 */ export const $messages = importAllLang() export const $lang = getLang() const i18n = createI18n({ legacy: false, locale: $lang, messages: $messages }) /* 獲取語言 */ export function getLang() { const lang = Storage.get(langKey) return lang || langVal } /** * 持久化存儲 * @param lang 語言類型 zh-CN / zh-TW / en-US */ export function setLang(lang, reload = false) { if(getLang() !== lang) { Storage.set(langKey, lang || '') // 設置全局語言 // i18n.global.locale.value = lang // 重載頁面 if(reload) { window.location.reload() } } } /** * 自動化導入本地locale目錄下語言配置 */ export function importAllLang() { const langModule = {} try { const localeCtx = require.context('@/locale', true, /([a-z]{2})-?([A-Z]{2})?\.js$/) localeCtx.keys().map(path => { const pathCtx = localeCtx(path) if(pathCtx.default) { const pathName = path.replace(/(.*\/)*([^.]+).*/ig, '$2') if(langModule[pathName]) { langModule[pathName] = { ...langModule[pathName], ...pathCtx.default } }else { langModule[pathName] = pathCtx.default } } }) } catch (error) { console.log(error) } return langModule }
項目佈局分爲Auth和Main兩個主要模塊。vue-cli
<template> <div class="vadmin__wrapper"> <router-view class="vadmin__layouts-auth"></router-view> </div> </template> <script> import { useRoute } from "vue-router" import useTitle from '@/hooks/useTitle' export default { components: {}, setup() { const route = useRoute() // 設置標題 useTitle(route) } } </script>
<template> <div class="vadmin__wrapper" :style="{'--themeSkin': store.state.skin}"> <div v-if="!route.meta.isNewin" class="vadmin__layouts-main flexbox flex-col"> <!-- 頂部導航 --> <div class="layout__topbar"> <TopNav /> </div> <div class="layout__workpanel flex1 flexbox"> <!-- 側邊欄 --> <div v-show="rootRouteEnable" class="panel__leftlayer"> <SideMenu :routes="mainRoutes" :rootRoute="rootRoute" /> </div> <!-- 中間欄 --> <div class="panel__middlelayer" :class="{'collapsed': collapsed}"> <RouteMenu :routes="getAllRoutes" :rootRoute="rootRoute" :defaultActive="defaultActive" :rootRouteEnable="rootRouteEnable" /> </div> <!-- //右邊欄 --> <div class="panel__rightlayer flex1 flexbox flex-col"> <!-- 麪包屑 --> <BreadCrumb /> <v3-scroll autohide> <div class="lay__container"> <permission :roles="route.meta.roles"> <template #tooltips> <Forbidden /> </template> <router-view></router-view> </permission> </div> </v3-scroll> </div> </div> </div> <router-view v-else class="vadmin__layouts-main flexbox flex-col"></router-view> </div> </template>
爲了簡化圖表調用,封裝一個圖表hooks。使用到了element-resize-detector來監測dom尺寸變化。segmentfault
import { onMounted, onBeforeUnmount, ref } from "vue" import * as echarts from "echarts" import elementResizeDetectorMaker from "element-resize-detector" import utils from "@/utils" export default function useChart(refs, options) { let chartInst let chartRef = ref(null) let erd = elementResizeDetectorMaker() const handleResize = utils.debounce(() => { chartInst.resize() }, 100) onMounted(() => { if(refs.value) { chartInst = echarts.init(refs.value) chartInst.setOption(options) chartRef.value = chartInst } erd.listenTo(refs.value, handleResize) }) onBeforeUnmount(() => { chartInst.dispose() erd.removeListener(refs.value, handleResize) }) return chartRef }
這樣每次調用的時候,只需傳入圖表dom元素和圖表數據便可快速生成一個圖表。windows
Okey,運用electron+vite.js跨端開發後臺管理系統暫時分享到這裏。app
最後附上Electron+Vue3桌面端仿都有短視頻+直播
https://segmentfault.com/a/1190000039725671echarts