注册 登录
x***@126.com
x***@126.com
  • 发布:2021-05-19 18:22
  • 更新:2021-05-19 18:22
  • 阅读:4715

vite.js+vue3+electron12.0.4超清爽UI界面前端中后台管理系统

分类:HTML5+

上次有给大家分享一个Electron跨端仿抖音短视频项目,这次带来最新研发的vite.js+electron开发vue3中后台管理系统。

vite2-vue3-electronAdmin:一套基于electron+vite.js和element-plus组件库开发的客户端后台管理系统EXE。使用了最新的vue3全家桶技术,内置了 Vue-i18n 国际化解决方案,支持PC桌面端和平板自适应布局。

electron12 vite2.x仿制抖音短视频|直播聊天

img

基于最新的前端技术栈vite2+vue3全家桶+electron12+element-plus+echarts5开发而来。

img

技术栈

  • 编码器:VScode
  • 构建工具:Vitejs
  • vue3全家桶: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
  • 图表组件:Echarts^5.1
  • 国际化:vue-i18n^9.1
  • 模拟请求:mockjs^1.1

img

特性

  • 使用最新前端技术栈开发
  • 支持桌面端及平板响应式布局
  • 支持组件式+指令式两种权限认证方式
  • 支持中英文/繁体国际化方案
  • 支持表格拖拽排序、全屏表格、树形表格等功能
  • 支持个性化换肤

img

项目结构

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

main.js配置

/**  
 * 渲染进程主入口  
 * @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')  
})

vue-router路由配置

项目中的路由采用了结构化分层加载,分为验证路由authRoutes.js和主模块路由mainRoutes.js两大部分。

/**  
 * 路由配置 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()  
})

electron-vue3自定义仿Mac导航栏

项目中顶部导航条采用的是mac导航条风格,关闭/最小化/最大化按钮在左侧。
img

<!-- //仿Mac导航条 -->  
<template>  
    <WinBar zIndex="1000">  
        <template #wbtn>  
            <MsgMenu />  
            <Lang />  
            <a class="wbtn" @click="handleSkinWin"><i class="iconfont icon-huanfu"></i></a>  
            <Setting />  
            <a class="wbtn" @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-i18n国际化方案

img

新建一个locale目录用来存放项目中语言文件。

img

/**  
 * @desc    vue-i18n国际化配置文件  
 * @Time    andy by 2021-05  
 * @Author      Q:282310962  wx:xy190310  
 */  

import { createI18n } from 'vue-i18n'  
import Storage from '@/utils/storage'  

// 默认设置  
export const langKey = 'lang'  
export const langVal = 'zh-CN'  

/**  
 * 引入element-plus国际化包  
 */  
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 = importLang()  
export const $lang = getLang()  
const i18n = createI18n({  
    legacy: false,  
    locale: $lang,  
    messages: $messages  
})  

/**  
 * 自动导入语言配置  
 */  
export function importLang() {  
    const localeModule = {}  
    try {  
        // 导入 @/layouts 文件夹下包含子目录locale中的xxx.js文件  
        const layoutsCtx = require.context('@/layouts', true, /[/\\]locale[/\\]([a-z]{2})-?([A-Z]{2})?\.js$/)  
        layoutsCtx.keys().map(path => {  
            const pathCtx = layoutsCtx(path)  
            if(pathCtx.default) {  
                const pathName = path.replace(/(.*\/)*([^.]+).*/ig, '$2')  
                if(localeModule[pathName]) {  
                    localeModule[pathName] = {  
                        ...localeModule[pathName], ...pathCtx.default  
                    }  
                }else {  
                    localeModule[pathName] = pathCtx.default  
                }  
            }  
        })  
    } catch (error) {  
        console.log(error)  
    }  

    return localeModule  
}  

/**  
 * 存储设置语言  
 * @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()  
        }  
    }  
}  

/**  
 * 获取语言  
 */  
export function getLang() {  
    const lang = Storage.get(langKey)  
    return lang || langVal  
}

vite2+electron主模板布局

项目整体分为顶部导航条、侧边栏、路由菜单、右侧上面包屑导航、右侧下主体内容。

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

Vue3图表化Hook

项目中多个地方需要使用到图表功能,于是就封装了一个图表hook函数。

/**  
 * 封装图表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  
}

Okay,基于vite.js+vue3+electron开发管理后台就分享到这里。希望对小伙伴们有些帮助!

img

链接: https://juejin.cn/post/6963310387945013261/
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 关注 分享

要回复文章请先 登录或注册

哆哆女性网五行八字起名姓名测试美名腾免费起名网轨迹系列炙手可热王字怎么起名女孩武汉人信汇正方形面积实践论母亲节祝福语简短语句异世罗马全面战争免费起名测名字打分测试结果姓马的宝起名英杰传系列给宝宝起名怎么起好lol成就系统生辰八字起名打分11月3号姬姓名字女孩起名廉政准则家纺新店起名大全美联储加息时间10月8日出生起名装修起什么名茶艺培训需要多少钱关于水仙花的传说呆子王妃北京龙城花园孙起名字孙姓男孩名字大全洒的商标起什么名字王姓的 起名淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻不负春光新的一天从800个哈欠开始有个姐真把千机伞做出来了国产伟哥去年销售近13亿充个话费竟沦为间接洗钱工具重庆警方辟谣“男子杀人焚尸”男子给前妻转账 现任妻子起诉要回春分繁花正当时呼北高速交通事故已致14人死亡杨洋拄拐现身医院月嫂回应掌掴婴儿是在赶虫子男孩疑遭霸凌 家长讨说法被踢出群因自嘲式简历走红的教授更新简介网友建议重庆地铁不准乘客携带菜筐清明节放假3天调休1天郑州一火锅店爆改成麻辣烫店19岁小伙救下5人后溺亡 多方发声两大学生合买彩票中奖一人不认账张家界的山上“长”满了韩国人?单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#青海通报栏杆断裂小学生跌落住进ICU代拍被何赛飞拿着魔杖追着打315晚会后胖东来又人满为患了当地回应沈阳致3死车祸车主疑毒驾武汉大学樱花即将进入盛花期张立群任西安交通大学校长为江西彩礼“减负”的“试婚人”网友洛杉矶偶遇贾玲倪萍分享减重40斤方法男孩8年未见母亲被告知被遗忘小米汽车超级工厂正式揭幕周杰伦一审败诉网易特朗普谈“凯特王妃P图照”考生莫言也上北大硕士复试名单了妈妈回应孩子在校撞护栏坠楼恒大被罚41.75亿到底怎么缴男子持台球杆殴打2名女店员被抓校方回应护栏损坏小学生课间坠楼外国人感慨凌晨的中国很安全火箭最近9战8胜1负王树国3次鞠躬告别西交大师生房客欠租失踪 房东直发愁萧美琴窜访捷克 外交部回应山西省委原副书记商黎光被逮捕阿根廷将发行1万与2万面值的纸币英国王室又一合照被质疑P图男子被猫抓伤后确诊“猫抓病”

哆哆女性网 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化