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

二、主要特性

  1. 前端技术栈Vite2、Vue3、Electron12、Element Plus、Vue-i18n、Echarts5.x、Sortable、Mockjs。
  2. 权限认证支持组件式+指令式两种方式。
  3. 支持中文/英文/繁体国际化解决方案。
  4. 支持表格拖拽排序、缩放、树形表格等功能。
  5. 支持加载动态权限菜单,多方式轻松权限控制。
  6. 高效率开发,整个框架已经搭建完毕,只需新增相应模块即可。

三、项目结构图

整个项目使用最新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 可响应点击事件。

<!-- //顶部导航 -->
<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>

对于自定义导航条的实现方式,由于之前有过相关分享文章,这里就不详细介绍了。

https://www.cnblogs.com/xiaoyan2017/p/14449570.html

◆ Vite2|electron项目布局模板

为了使得项目分层结构更加清晰,布局分为 Auth 和 Main 两大模块。

<!-- //Auth主模块模板 -->
<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>
<!-- //Main主模块模板 -->
<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>

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

◆ 路由权限管理

项目中的权限尺寸组件式和指令式两种模式。

<!-- //权限验证模板 -->
<template>
<slot v-if="isPermission"/>
<slot v-else name="tooltips">
<el-alert title="对不起,您没有权限操作此页面!" type="error" show-icon></el-alert>
</slot>
</template>
<script>
import { computed } from "vue";
import { useStore } from "vuex";
import { getPermissionRoute } from "@/utils/routes";
export default {
props: { roles: { type: [String, Array] } },
components: {},
setup(props) {
const store = useStore();
// 判断是否有权限
const isPermission = computed(() =>
getPermissionRoute(JSON.stringify(store.state.roles), props.roles)
);
return { isPermission };
}
};
</script>
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

组件调用

<Permission roles="test">
<template #tooltips>
<h2 style="color:red;">此模块只有test角色才能操作!</h2>
</template>
<el-button type="primary" icon="el-icon-search">查询</el-button>
</Permission> <el-divider /> <Permission roles="dev">
<template #tooltips>
<h2 style="color:red;">你无权操作Dev模块!</h2>
</template>
<el-button type="primary" icon="el-icon-edit">编辑</el-button>
<el-button type="warning" icon="el-icon-delete">删除</el-button>
</Permission>

指令调用

<el-button v-permission="'test'" type="primary" icon="el-icon-search">查询</el-button>
<el-button v-permission="'dev'" type="success" icon="el-icon-plus">新增</el-button>
<el-button v-permission="['test', 'dev']" type="warning" icon="el-icon-edit">编辑</el-button>
<el-button v-permission="['admin']" type="danger" icon="el-icon-delete">删除</el-button>

◆ 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

Electron-Vue3-Vadmin后台系统|vite2+electron桌面端权限管理系统的更多相关文章

  1. 分享一个基于ligerui的系统应用案例ligerRM V2(权限管理系统)(提供下载)

    阅读目录 简介 系统特色 系统介绍 - 首页 系统介绍 - 列表页 系统介绍 - 明细页(表单) 系统介绍 - 菜单/按钮 系统介绍 - 权限中心 系统介绍 - 数据权限 系统介绍 - 字段权限 系统 ...

  2. 基于vite2+electron12后台管理模板|Electron后台框架系统

    前一溜时间有给大家分享一个 electron+vite跨端短视频 项目.这次分享的是vite2.x和electron实现跨平台后台框架,支持国际化多语言配置.导航菜单+树形菜单两种路由菜单模式.展开/ ...

  3. Vite2+Electron仿抖音|vite2.x+electron12+vant3短视频|直播|聊天

    整合vite2+electron12跨平台仿抖音电脑版实战Vite2-ElectronDouYin. 基于vite2.0+electron12+vant3+swiper6+v3popup等技术跨端仿制 ...

  4. 快速了解Electron:新一代基于Web的跨平台桌面技术

    本文引用了作者“ ConardLi”的<用JS开发跨平台桌面应用,从原理到实践>一文部分内容,原文链接:segmentfault.com/a/1190000019426512,感谢原作者的 ...

  5. 【electron+vue3+ts实战便笺exe】一、搭建框架配置

    不要让自己的上限成为你的底线 前言 诈尸更新系列,为了跟上脚步,尝试了vue3,在学习vue3的时候顺便学习一手electron和ts,本教程将分别发布,源码会在最后的文章发布.因为还在开发中,目前也 ...

  6. Vite ❤ Electron——基于Vite搭建Electron+Vue3的开发环境【一】

    背景 目前社区两大Vue+Electron的脚手架:electron-vue和vue-cli-plugin-electron-builder, 都有这样那样的问题,且都还不支持Vue3,然而Vue3已 ...

  7. 【electron+vue3+ts实战便笺exe】二、electron+vue3开发内容

    不要让自己的上限成为你的底线 本来以为有万字的..没想到才堪堪近6000字.为了水文的嫌疑,只挑了重点的地方讲,比如component内的组件就挑了右键弹窗去说明,建议在看本文的时候边查看项目,有不懂 ...

  8. 【原创】从零开始搭建Electron+Vue+Webpack项目框架(六)Electron打包,同时构建客户端和web端

    导航: (一)Electron跑起来(二)从零搭建Vue全家桶+webpack项目框架(三)Electron+Vue+Webpack,联合调试整个项目(四)Electron配置润色(五)预加载及自动更 ...

  9. 【Electron】在 WSL2 中 打包 electron Linux 版本

    [Electron]在 WSL2 中 打包 electron Linux 版本. 安装 WSL 我使用的是 Ubuntu 20.04.4 LTS 的版本. 安装 WSL 文档地址:https://do ...

随机推荐

  1. 利用eigen库简单实现矩阵功能

    eigen是目前运行速度较快的C++矩阵运算库,而且其轻便小巧安装方便的特点简直是吸引人啊!特做此笔记,记录一下这个安装简单.体积轻巧.功能强大的C++库. 1. Download and Insta ...

  2. PAT (Advanced Level) Practice 1041 Be Unique (20 分) 凌宸1642

    PAT (Advanced Level) Practice 1041 Be Unique (20 分) 凌宸1642 题目描述: Being unique is so important to peo ...

  3. CentOS 7.6部署Vue + SrpingBoot + MySQL单体项目

    对于独立的项目(前端.后台单体服务.数据库),部署到新服务器上时,常常需要繁琐的配置与环境安装,这里介绍Centos 7.6下如何搭建基于Docker的环境,以及如何使用docker部署一套Vue + ...

  4. 如何优雅地学习计算机2<-->Helloworld

    0.导入 ​ 在进行粗略的学习计算机底层知识和变量后,我们来开始编写年轻人的第一个程序--Helloworld. ​ 我们需要用到的工具有:1.Dev-C++(也可以使用其他软件)2.脑子(最重要) ...

  5. Kubernetes Secrets

    Secrets 背景信息 Kubernetes版本 [09:08:04 yhf@test ~]$ kubectl version Client Version: version.Info{Major: ...

  6. Linux Nvidia显卡驱动安装

    1 概述 因为某些需要需要在Linux上安装显卡驱动,这里记录一下安装过程. 2 环境 Manjaro RTX 2060 3 下载驱动安装包 到官网上搜索下载即可,可以戳这里: 选择自己的显卡型号即可 ...

  7. linux 在某个路径下,查找某个文件

    find /cephfs/netdisk/ -name "*.sql"

  8. Bug Hunt UVA - 1596

      In this problem, we consider a simple programming language that has only declarations of onedimens ...

  9. 功能:SpringBoot日志配置详情

    SpringBoot日志配置详情 一.介绍 在所有的项目中,日志是必不可少的,为了高效清晰的查找日志,可以配置日志输出的等级和格式. 在配置后,可以自定义输出日志到指定目录,可以按照天数来分割日志,可 ...

  10. 利用宝塔面板搭建 Laravel 5.5 环境

    1.更新系统 yum install epel-release #rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest- ...