基于vite2.x+electron12桌面端后台管理系统Vite2ElectronVAdmin。
继上一次分享vite2整合electron搭建后台框架,这次带来的是最新开发的跨桌面中后台权限管理系统。使用最新的前端技术栈,内置 i18n 国际化解决方案,动态权限路由,权限验证,整合了典型的表格/表单等业务模块功能。
一、技术栈
- 编码器:vscode
- vue3技术:vite2.1.5+vue3.0+vuex4+vue-router@4
- 跨端框架:electron^12.0.4
- 打包工具:vue-cli-plugin-electron-builder
- UI组件库:element-plus^1.0.2 (饿了么vue3组件库)
- 表格拖拽:sortablejs^1.13.0
- 图表组件:echarts^5.1.1
- 国际化方案:vue-i18n^9.1.6
- 数据模拟:mockjs^1.1.0
二、主要特性
- 前端技术栈Vite2、Vue3、Electron12、Element Plus、Vue-i18n、Echarts5.x、Sortable、Mockjs。
- 权限认证支持组件式+指令式两种方式。
- 支持中文/英文/繁体国际化解决方案。
- 支持表格拖拽排序、缩放、树形表格等功能。
- 支持加载动态权限菜单,多方式轻松权限控制。
- 高效率开发,整个框架已经搭建完毕,只需新增相应模块即可。
三、项目结构图
整个项目使用最新vue3语法编码,采用标准的分层目录结构形式,数据均是使用Mock.js进行模拟。
◆ electron支持多开新窗口
项目支持打开多个窗口,如主题换肤、关于等窗口。只需通过如下的方式调用即可。
import { winCfg, createWin } from '@/windows/actions' // 换肤窗口 const handleOpenTheme = () => { createWin({ title: '个性装扮', route: '/skin', width: 750, height: 480, modal: true, parent: winCfg.window.id, resize: false, }) }
大家如果对electron创建多窗口模式感兴趣的话,可以去看看下面这篇文章。
https://www.cnblogs.com/xiaoyan2017/p/14403820.html
◆ electron实现无边框Mac导航栏效果
如上图:顶部导航栏默认是Mac风格,也支持自定义标题、背景/文字颜色、是否沉浸式透明背景等功能。
设置 -webkit-app-region: drag 实现导航条可拖拽,标题及按钮 -webkit-app-region:no-drag 可响应点击事件。
对于自定义导航条的实现方式,由于之前有过相关分享文章,这里就不详细介绍了。
https://www.cnblogs.com/xiaoyan2017/p/14449570.html
◆ Vite2|electron项目布局模板
为了使得项目分层结构更加清晰,布局分为 Auth 和 Main 两大模块。
◆ Vue-Router路由配置
/** * 路由配置 Router util * @author XiaoYan */ import { createRouter, createWebHashHistory } from "vue-router" import { ElLoading } from "element-plus" import { loginWin } from "@/windows/actions" import store from '@/store' // 导入公共模板/路由配置 import mainLayout from "@/layouts/main" import authLayout from "@/layouts/auth" import mainRoutes from "@/layouts/main/routes.js" import authRoutes from "@/layouts/auth/routes.js" const RoutesLs = [ // 主页面模块 { path: '/', redirect: '/home/index', component: mainLayout, children: mainRoutes, }, // 验证模块 { path: '/auth', redirect: '/auth/login', component: authLayout, children: authRoutes, }, // 错误模块 { path: '/:pathMatch(.*)*', component: () => import('@/views/error/404.vue'), meta: { title: 'app__global-page-notfound', } } ] const router = createRouter({ history: createWebHashHistory(), routes: RoutesLs, }) // 全局钩子拦截验证状态 let loadingIns router.beforeEach((to, from, next) => { // 开启加载提示 loadingIns = ElLoading.service({ lock: true, text: 'Loading...', spinner: 'el-icon-loading', background: 'rgba(19, 209, 122, .1)' }) // 判断当前路由是否需要验证状态 const isLogined = store.state.isLogin if(to.meta.auth) { if(isLogined) { next() }else { loginWin() loadingIns.close() } }else { next() } }) router.afterEach(() => { // 关闭加载提示 loadingIns.close() })
◆ Vue-I18n国际化解决方案
项目中路由采用了 vue-i18n 国际化,支持中文|繁体|英文三种语言。
目前vue-i18n插件支持vue3项目了,大家需安装最新版本即可。
npm i vue-i18n@next -D
如上图:新建locale目录用来处理相应模块语言配置。
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 })
◆ 动态化图表Hooks
项目中图表是使用最新的Echarts组件。为了避免每次都使用echarts.init调用图表接口。于是就封装了调用图表hook函数。
一开始是使用监听window.resize来自适应图表尺寸,这里有一个bug,只有窗口大小改变才会触发,而DOM改变则不会触发了,于是改用 element-resize-detector 来监听,完美解决问题。
/** * 动态化图表Hook * @author XiaoYan */ 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 } // window.addEventListener('resize', handleResize) erd.listenTo(refs.value, handleResize) }) onBeforeUnmount(() => { chartInst.dispose() // window.removeEventListener('resize', handleResize) erd.removeListener(refs.value, handleResize) }) return chartRef }
◆ 路由权限管理
项目中的权限尺寸组件式和指令式两种模式。
import store from "@/store" import { getPermissionRoute } from "@/utils/routes" const Permission = (el, binding) => { const { value } = binding if(value) { const userRoles = JSON.stringify(store.state.roles) if(!getPermissionRoute(userRoles, value)) { el.parentNode && el.parentNode.removeChild(el) } }else { console.error(`Set Roles! Like v-permission="['admin', 'dev']" or v-permission="'test'"`) } } export default Permission
组件调用
此模块只有test角色才能操作!
查询你无权操作Dev模块!
编辑删除指令调用
查询新增编辑删除
◆ electron-builder打包配置
{ "productName": "electron-vadmin", "appId": "cc.xiaoyan.electron-vadmin", "copyright": "Copyright © 2021-present XiaoYan", "compression": "maximum", "asar": false, "extraResources": [{ "from": "./resource","to": "resource" }], "nsis": { "oneClick": false, "allowToChangeInstallationDirectory": true, "perMachine": true, "deleteAppDataOnUninstall": true, "createDesktopShortcut": true, "createStartMenuShortcut": true, "shortcutName": "ElectronVAdmin" }, "win": { "icon": "./resource/shortcut.ico", "artifactName": "${productName}-v${version}-${platform}-${arch}-setup.${ext}", "target": [{ "target": "nsis","arch": ["ia32"] }] }, "mac": { "icon": "./resource/shortcut.icns","artifactName": "${productName}-v${version}-${platform}-${arch}-setup.${ext}" }, "linux": { "icon": "./resource","artifactName": "${productName}-v${version}-${platform}-${arch}-setup.${ext}" } }
最后还需注意
1、项目路径命名不能包含中文,否则打包会报错!
2、尽量不要使用 getCurrentInstance 函数来使用router或store,打包也会报错!
3、打包后运行出现白屏情况,可配置 history: createWebHashHistory()
4、提示fs.existsSync错误,设置nodeIntegration: true开启Node支持;
好了,基于vite2+electron开发后台管理系统就分享到这里,希望对大家有些帮助~
最后附上一个electron+vue3+vant短视频项目
https://www.cnblogs.com/xiaoyan2017/p/14585223.html
本文为博主原创文章,未经博主允许不得转载,欢迎大家一起交流 QQ(282310962) wx(xy190310)