前一溜時間有給大家分享一個 electron+vite跨端短視頻 項目。這次分享的是vite2.x和electron實現跨平台后台框架,支持國際化多語言配置、導航菜單+樹形菜單兩種路由菜單模式、展開/收縮路由菜單等功能。
vite2-electron-system 后台模板框架使用到的版本:vite2.1.51、vue3.0.5、electron12.0.4
-
vite2.x|vue3-i18n國際化多語言
項目支持如下圖3種語言切換[中文/英文/繁體],使用Vue I18n國際化vue3版本。
// 安裝vue-i18n插件
npm i vue-i18n@next -D
在布局模板中新建locale多語言配置文件。
/** * @desc 國際化語言配置(主模板) */ export default { 'layout__main-menu__home': '首頁', 'layout__main-menu__home_dashboard': '控制台', 'layout__main-menu__home_breadcrumbs': '自定義面包屑導航', 'layout__main-menu__home_breadcrumbs-link': 'https://cn.vitejs.dev/', 'layout__main-menu__home_docs': '自定義鏈接', 'layout__main-menu__home_tree': '樹形菜單', 'layout__main-menu__component': '組件', 'layout__main-menu__component_table': '表格', 'layout__main-menu__component_table-all': '所有表格', 'layout__main-menu__component_table-custom': '自定義表格', 'layout__main-menu__component_table-search': '表格搜索', 'layout__main-menu__component_table-search-list': '搜索列表', 'layout__main-menu__component_form': '表單', 'layout__main-menu__component_form-all': '所有表單', 'layout__main-menu__component_form-custom': '自定義表單', 'layout__main-menu__component_editor': '富文本編輯器', }
在plugins目錄下新建一個i18n.js配置文件。
/** * vue-i18n國際化配置文件 */ 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 } export default i18n
然后在main.js中導入配置。
// 引入element-plus組件庫 import ElPlus from 'element-plus' // 引入多語言 import VueI18n, { ElPlusLang, getLang } from '@/plugins/i18n' app.use(ElPlus, { size: 'small', locale: ElPlusLang[getLang()] }) app.use(VueI18n)
-
vite2|vue3.0動態Hook設置標題
如下圖:項目中頁面路由跳轉,動態化顯示標題。
vue3 hook 就能快速實現動態切換,在hook目錄新建一個useTitle.js文件。
/** * 動態獲取路由標題 */ import { onMounted, watchEffect } from 'vue' import { useI18n } from 'vue-i18n' export default function useTitle(route) { console.log(route) if(!route.meta) return const { t } = useI18n() const defaultTitle = 'ELECTRON-VUE3-VADMIN' const Title = () => { if(route.meta.title) { document.title = `${t(route.meta.title)} - ${defaultTitle}` }else { document.title = defaultTitle } } watchEffect(Title) onMounted(() => { Title() }) }
調用非常簡單,通過如下方式即可快速實現路由地址切換標題。
import { useRoute } from 'vue-router' import useTitle from '@/hooks/useTitle' export default { setup() { const route = useRoute() // 設置title useTitle(route) return { // ... } } }
-
vite2.x路由載等待效果
為了避免出現等待白屏的情況,可以在路由跳轉的時候加入loading提示。
使用了element-plus的loading組件。
let loadingInstance // 全局鈎子攔截登錄狀態 router.beforeEach((to, from, next) => { // 加載提示(避免白屏等待) // 可以使用NProgress組件:https://ricostacruz.com/nprogress/ loadingInstance = ElLoading.service({ lock: true, text: 'Loading', spinner: 'el-icon-loading', background: 'rgba(255, 255, 255, 0.7)' }) const hasLogined = store.state.isLogin // 判斷當前路由地址是否需要登錄權限 if(to.meta.auth) { if(hasLogined) { next() }else { // 跳轉登錄頁面 loginWin() } }else { next() } }) router.afterEach(() => { // 關閉加載提示 loadingInstance.close() })
大家根據需要也可以選擇一款非常小巧強大的NProgress插件實現加載效果。
https://ricostacruz.com/nprogress/
-
vite2+element-plus路由菜單
項目中使用了elementUI導航菜單 el-menu 和樹形菜單 el-tree 兩種實現路由地址菜單。
<!-- el-menu導航菜單路由 --> <div> <el-menu :default-active="defaultActive" :collapse="collapsed" :collapse-transition="false" class="mainLayout__menuNav" @select="handleNodeSelect" > <sidebar-item v-for="route in allRoutes" :key="route.path" :item="route" :isNavEnable="isNavEnable" :rootsRoute="rootsRoute" /> </el-menu> </div> <!-- el-tree樹形菜單路由 --> <el-tree ref="treeRef" :data="allRoutes" :props="defaultProps" @node-click="handleNodeSelect" node-key="path" :default-expanded-keys="[rootsRoute, defaultActive]" :default-checked-keys="[defaultActive]" highlight-current show-checkbox check-strictly > </el-tree>
如何讓el-tree樹形菜單組件一次只能選中一個路由?開啟 highlight-current 和 check-strictly 屬性。
highlight-current:是否高亮當前選中節點,默認值是 false。
check-strictly:在顯示復選框的情況下,是否嚴格的遵循父子不互相關聯的做法,默認為 false
通過watchEffect監聽路由地址變化動態更新選中節點。
// 選擇節點 const handleNodeSelect = (data) => { // console.log(data); if(data.children) return if(utils.checkExternal(data.path)) { alert(data.path) }else { treeRef.value.setCheckedKeys([data.path], true) router.push(data.path) } } // 監聽路由變化,設置選中節點 const routeChanged = async () => { if(!treeRef.value) return treeRef.value.setCheckedKeys([route.path], true) } watchEffect(routeChanged)
另外還需自定義選中行的顏色樣式。
// 樹形睬単el-tree樣式 .indexlayout-treemenu { border: 3px dashed #f90; padding: 10px; // 選中行顏色 .el-tree--highlight-current .el-tree-node.is-checked>.el-tree-node__content { background: $--color-primary; color: #fff; } }
另外附上自定義路由JSON文件。
/** * @desc 主頁面路由集合 * @author ANDY * ----------------------------------------- * 路由參數說明: * path: '/home' 鏈接 * redirect: '' 路徑重定向 * meta: { * auth: true 需要登錄驗證 * icon: 'home' 顯示側邊欄圖標(1、使用iconfont icon-xxx 2、使用餓了么el-icon-xxx) * title: '標題' 名稱(顯示在側邊欄/面包屑/瀏覽器title) * breadcrumb: [ 面包屑導航 * { * title: '標題' 標題 * path: '/demo' 鏈接 * } * ] * activeRoute: '/home/dashboard' 側邊欄鏈接選中,默認route.path * rootsRoute: '/home' 所屬頂部鏈接選中 * } */ import emptyLayout from '@/layouts/empty.vue' const mainRoutes = [ // 首頁模塊 { path: '/home', redirect: '/home/dashboard', component: emptyLayout, meta: { auth: true, //是否登錄驗證 icon: 'icon-ding', title: 'layout__main-menu__home', hidden: false, //隱藏菜單項 }, children: [ { path: 'dashboard', component: () => import('@/views/dashboard.vue'), meta: { auth: true, icon: 'icon-haoyou', title: 'layout__main-menu__home_dashboard' } }, { path: 'breadcrumbs', component: () => import('@/views/breadcrumbs/index.vue'), meta: { auth: true, icon: 'icon-down', title: 'layout__main-menu__home_breadcrumbs', // 自定義面包屑 breadcrumb: [ { title: 'layout__main-menu__home_breadcrumbs', path: '/home/breadcrumbs' }, { title: 'layout__main-menu__home', path: '/home' }, { title: 'layout__main-menu__home_breadcrumbs-link', path: 'https://cn.vitejs.dev/' } ] } }, { path: 'https://cn.vitejs.dev/', meta: { // auth: true, icon: 'icon-go', title: 'layout__main-menu__home_docs', rootsRoute: '/home' } }, { path: 'tree', component: () => import('@/views/component/tree/index.vue'), meta: { auth: true, icon: 'el-icon-s-data', title: 'layout__main-menu__home_tree' }, }, ] }, // 組件模塊 { path: '/component', redirect: '/component/table/allTable', component: emptyLayout, meta: { auth: true, //是否登錄驗證 icon: 'el-icon-s-operation', title: 'layout__main-menu__component', hidden: false, //隱藏菜單項 }, children: [ { path: 'table', redirect: '/component/table/allTable', component: emptyLayout, meta: { auth: true, icon: 'el-icon-s-grid', title: 'layout__main-menu__component_table' }, children: [ { path: 'allTable', component: () => import('@/views/component/table/all.vue'), meta: { title: 'layout__main-menu__component_table-all' } }, { path: 'customTable', component: () => import('@/views/component/table/custom.vue'), meta: { title: 'layout__main-menu__component_table-custom' } }, { path: 'search', redirect: '/component/table/search/searchlist', component: emptyLayout, meta: { title: 'layout__main-menu__component_table-search' }, children: [ { path: 'searchlist', component: () => import('@/views/component/table/search.vue'), meta: { title: 'layout__main-menu__component_table-search-list' } } ] } ] }, { path: 'form', redirect: '/component/form/allForm', component: emptyLayout, meta: { auth: true, icon: 'el-icon-cpu', title: 'layout__main-menu__component_form' }, children: [ { path: 'allForm', component: () => import('@/views/component/form/all.vue'), meta: { title: 'layout__main-menu__component_form-all' } }, { path: 'customForm', component: () => import('@/views/component/form/custom.vue'), meta: { title: 'layout__main-menu__component_form-custom' } } ] }, { path: 'editor', component: () => import('@/views/component/editor/index.vue'), meta: { auth: true, icon: 'el-icon-cpu', title: 'layout__main-menu__component_editor' }, }, ] }, // 更多路由配置... ] export default mainRoutes
OK,以上就是基於vite2和electron開發簡易后台模板的一些分享,希望對大家有所幫助哈~~ 😘
最后附上一個vue3+elementPlus網頁pc版聊天實例
https://www.cnblogs.com/xiaoyan2017/p/14307849.html