Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

  • Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE已关闭评论
  • 205 次浏览
  • A+
所属分类:Web前端
摘要

基于tauri+vite4+pinia2 跨端后台管理系统应用实例TauriAdmin。 tauri-admin 基于最新跨端技术 Tauri Rust webview2 整合 Vite4 构建桌面端通用后台管理解决方案。搭载轻量级ve-plus组件库 、支持多窗口切换管理、vue-i18n多语言包、动态路由权限、常用业务功能模块、3种布局模板及动态路由缓存 等功能。

基于tauri+vite4+pinia2跨端后台管理系统应用实例TauriAdmin

tauri-admin 基于最新跨端技术 Tauri Rust webview2 整合 Vite4 构建桌面端通用后台管理解决方案。搭载轻量级ve-plus组件库、支持多窗口切换管理、vue-i18n多语言包、动态路由权限、常用业务功能模块、3种布局模板及动态路由缓存等功能。

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

使用技术

  • 编码工具:vscode
  • 框架技术:tauri+vite^4.2.1+vue^3.2.45+pinia+vue-router
  • UI组件库:ve-plus (基于vue3轻量级UI组件库)
  • 样式处理:sass^1.63.6
  • 图表组件:echarts^5.4.2
  • 国际化方案:vue-i18n^9.2.2
  • 编辑器组件:wangeditor^4.7.15
  • 持久化缓存:pinia-plugin-persistedstate^3.1.0

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

目前tauri已经迭代到1.4,如果大家对tauri+vue3创建多窗口项目感兴趣,可以去看看之前的这篇分享文章。

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

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

功能特性

  1. 使用跨端技术tauri1.4
  2. 最新前端技术栈vite4、vue3、pinia、vue-router、vue-i18n
  3. 支持中文/英文/繁体多语言解决方案
  4. 支持动态路由权限验证
  5. 支持路由缓存功能/tabs控制切换路由页面
  6. 内置多个模板布局风格
  7. 搭配轻量级vue3组件库veplus
  8. 高效开发,支持增删定制化页面模块

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

项目结构

使用tauri脚手架搭配vite4构建项目,整体采用vue3 setup语法编码开发。

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

主入口main.js

import { createApp } from "vue" import "./styles.scss" import App from "./App.vue"  // 引入路由及状态管理 import Router from './router' import Pinia from './pinia'  // 引入插件配置 import Libs from './libs'  const app = createApp(App)  app .use(Router) .use(Pinia) .use(Libs) .mount("#app")

Tauri-Admin布局模板

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

提供了三种常见的布局模板,大家也可以定制喜欢的模板样式。

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

<script setup>     import { computed } from 'vue'     import { appStore } from '@/pinia/modules/app'      // 引入布局模板     import Columns from './template/columns/index.vue'     import Vertical from './template/vertical/index.vue'     import Transverse from './template/transverse/index.vue'      const store = appStore()     const config = computed(() => store.config)      const LayoutConfig = {         columns: Columns,         vertical: Vertical,         transverse: Transverse     } </script>  <template>     <div class="veadmin__container" :style="{'--themeSkin': store.config.skin}">         <component :is="LayoutConfig[config.layout]" />     </div> </template>

路由/pinia状态管理

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

如上图:配置router路由信息。

/**  * 路由配置  * @author YXY    Q:282310962  */  import { appWindow } from '@tauri-apps/api/window' import { createRouter, createWebHistory } from 'vue-router' import { appStore } from '@/pinia/modules/app' import { hasPermission } from '@/hooks/usePermission' import { loginWin } from '@/multiwins/actions'  // 批量导入modules路由 const modules = import.meta.glob('./modules/*.js', { eager: true }) const patchRoutes = Object.keys(modules).map(key => modules[key].default).flat()  /**  * @description 动态路由参数配置  * @param path ==> 菜单路径  * @param redirect ==> 重定向地址  * @param component ==> 视图文件路径  * 菜单信息(meta)  * @param meta.icon ==> 菜单图标  * @param meta.title ==> 菜单标题  * @param meta.activeRoute ==> 路由选中(默认空 route.path)  * @param meta.rootRoute ==> 所属根路由选中(默认空)  * @param meta.roles ==> 页面权限 ['admin', 'dev', 'test']  * @param meta.breadcrumb ==> 自定义面包屑导航 [{meta:{...}, path: '...'}]  * @param meta.isAuth ==> 是否需要验证  * @param meta.isHidden ==> 是否隐藏页面  * @param meta.isFull ==> 是否全屏页面  * @param meta.isKeepAlive ==> 是否缓存页面  * @param meta.isAffix ==> 是否固定标签(tabs标签栏不能关闭)  * */ const routes = [     // 首页     {         path: '/',         redirect: '/home'     },     // 错误模块     {         path: '/:pathMatch(.*)*',         component: () => import('@views/error/404.vue'),         meta: {             title: 'page__error-notfound'         }     },     ...patchRoutes ]  const router = createRouter({     history: createWebHistory(),     routes })  // 全局钩子拦截 router.beforeEach((to, from, next) => {     // 开启加载提示     loading({         text: 'Loading...',         background: 'rgba(70, 255, 170, .1)',         onOpen: () => {             console.log('开启loading')         },         onClose: () => {             console.log('关闭loading')         }     })          const store = appStore()     if(to?.meta?.isAuth && !store.isLogged) {         loginWin()         loading.close()     }else if(!hasPermission(store.roles, to?.meta?.roles)) {         // 路由鉴权         appWindow?.show()         next('/error/forbidden')         loading.close()         Notify({             title: '访问限制!',             description: `<span style="color: #999;">当前登录角色 ${store.roles} 没有操作权限,请联系管理员授权后再操作。</div>`,             type: 'danger',             icon: 've-icon-unlock',             time: 10         })     }else {         appWindow?.show()         next()     } })  router.afterEach(() => {     loading.close() })  router.onError(error => {     loading.close()     console.warn('Router Error》》', error.message); })  export default router

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

如上图:vue3项目搭配pinia进行状态管理。

/**  * 状态管理 Pinia util  * @author YXY  */  import { createPinia } from 'pinia' // 引入pinia本地持久化存储 import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'  const pinia = createPinia() pinia.use(piniaPluginPersistedstate)  export default pinia

自定义路由菜单

项目中的三种模板提供了不同的路由菜单。均是基于Menu组件封装的RouteMenu菜单。

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

<script setup>   import { ref, computed, h, watch, nextTick } from 'vue'   import { useI18n } from 'vue-i18n'   import { Icon, useLink } from 've-plus'   import { useRoutes } from '@/hooks/useRoutes'   import { appStore } from '@/pinia/modules/app'    // 引入路由集合   import mainRoutes from '@/router/modules/main.js'    const props = defineProps({     // 菜单模式(vertical|horizontal)     mode: { type: String, default: 'vertical' },     // 是否开启一级路由菜单     rootRouteEnable: { type: Boolean, default: true },     // 是否要收缩     collapsed: { type: Boolean, default: false },      // 菜单背景色     background: { type: String, default: 'transparent' },     // 滑过背景色     backgroundHover: String,     // 菜单文字颜色     color: String,     // 菜单激活颜色     activeColor: String   })    const { t } = useI18n()   const { jumpTo } = useLink()   const { route, getActiveRoute, getCurrentRootRoute, getTreeRoutes } = useRoutes()   const store = appStore()    const rootRoute = computed(() => getCurrentRootRoute(route))   const activeKey = ref(getActiveRoute(route))   const menuOptions = ref(getTreeRoutes(mainRoutes))   const menuFilterOptions = computed(() => {     if(props.rootRouteEnable) {       return menuOptions.value     }     // 过滤掉一级菜单     return menuOptions.value.find(item => item.path == rootRoute.value && item.children)?.children   })    watch(() => route.path, () => {     nextTick(() => {       activeKey.value = getActiveRoute(route)     })   })    // 批量渲染图标   const batchRenderIcon = (option) => {     return h(Icon, {name: option?.meta?.icon ?? 've-icon-verticleleft'})   }    // 批量渲染标题   const batchRenderLabel = (option) => {     return t(option?.meta?.title)   }    // 路由菜单更新   const handleUpdate = ({key}) => {     jumpTo(key)   } </script>  <template>   <Menu     class="veadmin__menus"     v-model="activeKey"     :options="menuFilterOptions"     :mode="mode"     :collapsed="collapsed && store.config.collapse"     iconSize="18"     key-field="path"     :renderIcon="batchRenderIcon"     :renderLabel="batchRenderLabel"     :background="background"     :backgroundHover="backgroundHover"     :color="color"     :activeColor="activeColor"     @change="handleUpdate"     style="border: 0;"   /> </template>

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Menu组件支持横向/竖向排列,调用非常简单。

<RouteMenu     :rootRouteEnable="false"     backgroundHover="#f1f8fb"     activeColor="#24c8db" />  <RouteMenu     rootRouteEnable     collapsed     background="#193c47"     backgroundHover="#1a5162"     color="rgba(235,235,235,.7)"     activeColor="#24c8db"     :collapsedIconSize="20" />  <RouteMenu     mode="horizontal"     background="#193c47"     backgroundHover="#1a5162"     color="rgba(235,235,235,.7)"     activeColor="#24c8db"     arrowIcon="ve-icon-caretright" />

tauri-admin多语言配置

tauri-vue3-admin项目使用vue-i18n进行多语言处理。

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

import { createI18n } from 'vue-i18n' import { appStore } from '@/pinia/modules/app'  // 引入语言配置 import enUS from './en-US' import zhCN from './zh-CN' import zhTW from './zh-TW'  // 默认语言 export const langVal = 'zh-CN'  export default async (app) => {     const store = appStore()     const lang = store.lang || langVal      const i18n = createI18n({         legacy: false,         locale: lang,         messages: {             'en': enUS,             'zh-CN': zhCN,             'zh-TW': zhTW         }     })          app.use(i18n) }

路由缓存功能

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

项目支持配置路由页面缓存功能。可以在全局pinia/modules/app.js中配置,也可以在router配置项meta中配置isKeepAlive: true。

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

<template>   <div v-if="app.config.tabsview" class="veadmin__tabsview">     <Scrollbar ref="scrollbarRef" mousewheel>       <ul class="tabview__wrap">         <li           v-for="(tab,index) in tabOptions" :key="index"           :class="{'actived': tabKey == tab.path}"           @click="changeTab(tab)"           @contextmenu.prevent="openContextMenu(tab, $event)"         >           <Icon class="tab-icon" :name="tab.meta?.icon" />           <span class="tab-title">{{$t(tab.meta?.title)}}</span>           <Icon v-if="!tab.meta?.isAffix" class="tab-close" name="ve-icon-close" size="12" @click.prevent.stop="closeTab(tab)" />         </li>       </ul>     </Scrollbar>   </div>   <!-- 右键菜单 -->   <Dropdown     ref="contextmenuRef"     trigger="manual"     :options="contextmenuOptions"     fixed="true"     :render-label="handleRenderLabel"     @change="changeContextMenu"     style="height: 0;"   /> </template>

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

import { ref, nextTick } from 'vue' import { useRoute } from 'vue-router' import { defineStore } from 'pinia' import { appStore } from '@/pinia/modules/app'  export const tabsStore = defineStore('tabs', () => {         const currentRoute = useRoute()         const store = appStore()          /*state*/         const tabViews = ref([]) // 标签栏列表         const cacheViews = ref([]) // 缓存列表         const reload = ref(true) // 刷新标识          // 判断tabViews某个路由是否存在         const tabIndex = (route) => {             return tabViews.value.findIndex(item => item?.path === route?.path)         }          /*actions*/         // 新增标签         const addTabs = (route) => {             const index = tabIndex(route)             if(index > -1) {                 tabViews.value.map(item => {                     if(item.path == route.path) {                         // 当前路由缓存                         return Object.assign(item, route)                     }                 })             }else {                 tabViews.value.push(route)             }              // 更新keep-alive缓存             updateCacheViews()         }          // 移除标签         const removeTabs = (route) => {             const index = tabIndex(route)             if(index > -1) {                 tabViews.value.splice(index, 1)             }              // 更新keep-alive缓存             updateCacheViews()         }          // 移除左侧标签         const removeLeftTabs = (route) => {             const index = tabIndex(route)             if(index > -1) {                 tabViews.value = tabViews.value.filter((item, i) => item?.meta?.isAffix || i >= index)             }              // 更新keep-alive缓存             updateCacheViews()         }          // 移除右侧标签         const removeRightTabs = (route) => {             const index = tabIndex(route)             if(index > -1) {                 tabViews.value = tabViews.value.filter((item, i) => item?.meta?.isAffix || i <= index)             }              // 更新keep-alive缓存             updateCacheViews()         }          // 移除其它标签         const removeOtherTabs = (route) => {             tabViews.value = tabViews.value.filter(item => item?.meta?.isAffix || item?.path === route?.path)              // 更新keep-alive缓存             updateCacheViews()         }          // 移除所有标签         const clearTabs = () => {             tabViews.value = tabViews.value.filter(item => item?.meta?.isAffix)              // 更新keep-alive缓存             updateCacheViews()         }          // 更新keep-alive缓存         const updateCacheViews = () => {             cacheViews.value = tabViews.value.filter(item => store.config.keepAlive || item?.meta?.isKeepAlive).map(item => item.name)             console.log('cacheViews缓存路由>>:', cacheViews.value)         }          // 移除keep-alive缓存         const removeCacheViews = (route) => {             cacheViews.value = cacheViews.value.filter(item => item !== route?.name)         }          // 刷新路由         const reloadTabs = () => {             removeCacheViews(currentRoute)             reload.value = false             nextTick(() => {                 updateCacheViews()                 reload.value = true                 document.documentElement.scrollTo({ left: 0, top: 0 })             })         }          // 清空缓存         const clear = () => {             tabViews.value = []             cacheViews.value = []         }          return {             tabViews,             cacheViews,             reload,              addTabs,             removeTabs,             removeLeftTabs,             removeRightTabs,             removeOtherTabs,             clearTabs,             reloadTabs,             clear         }     },     // 本地持久化存储(默认存储localStorage)     {         // persist: true         persist: {             // key: 'tabsState',             storage: localStorage,             paths: ['tabViews', 'cacheViews']         }     } )

tauri.conf.json配置

{   "build": {     "beforeDevCommand": "yarn dev",     "beforeBuildCommand": "yarn build",     "devPath": "http://localhost:1420",     "distDir": "../dist",     "withGlobalTauri": false   },   "package": {     "productName": "tauri-admin",     "version": "0.0.0"   },   "tauri": {     "allowlist": {       "all": true,       "shell": {         "all": false,         "open": true       }     },     "bundle": {       "active": true,       "targets": "all",       "identifier": "com.tauri.admin",       "icon": [         "icons/32x32.png",         "icons/128x128.png",         "icons/128x128@2x.png",         "icons/icon.icns",         "icons/icon.ico"       ]     },     "security": {       "csp": null     },     "windows": [       {         "fullscreen": false,         "resizable": true,         "title": "tauri-admin",         "width": 1000,         "height": 640,         "center": true,         "decorations": false,         "fileDropEnabled": false,         "visible": false       }     ],     "systemTray": {       "iconPath": "icons/icon.ico",       "iconAsTemplate": true,       "menuOnLeftClick": false     }   } }

Cargo.toml配置

[package] name = "tauri-admin" version = "0.0.0" description = "基于tauri+vue3+vite4+pinia轻量级桌面端后台管理Tauri-Admin" authors = "andy <282310962@qq.com>" license = "" repository = "" edition = "2023"  # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html  [build-dependencies] tauri-build = { version = "1.4", features = [] }  [dependencies] tauri = { version = "1.4", features = ["api-all", "icon-ico", "icon-png", "system-tray"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0"  [features] # this feature is used for production builds or when `devPath` points to the filesystem # DO NOT REMOVE!! custom-protocol = ["tauri/custom-protocol"]

OK,基于tauri+vue3跨端后台管理系统就分享到这里。希望对大家有所帮助哈~~

最后附上两个最新开发的Electron和uniapp跨端项目实例

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

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

Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE