基于tauri+vite4+pinia跨端后台管理系统应用

基于tauri+vue3跨端开发桌面端后台管理系统应用TauriAdmin。

 

使用跨端技术tauri+rust搭配vite构建工具开发桌面端后台管理系统模板。内置了多种布局模板,实现了常用的`图表/表格/表单/图文编辑器/权限控制`等功能

 

 

tauri-admin支持多窗口切换管理、vue-i18n多语言包、动态路由权限、动态路由缓存等功能。

 

 

技术栈

  • 编码工具: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+vue3多窗口管理

基于tauri创建多开窗口,登录窗口切换到主窗口。

 

 

// 创建窗口参数配置

export const windowConfig = {

   label: null,            // 窗口唯一label

   title: '',              // 窗口标题

   url: '',                // 路由地址url

   width: 1000,            // 窗口宽度

   height: 640,            // 窗口高度

   minWidth: null,         // 窗口最小宽度

   minHeight: null,        // 窗口最小高度

   x: null,                // 窗口相对于屏幕左侧坐标

   y: null,                // 窗口相对于屏幕顶端坐标

   center: true,           // 窗口居中显示

   resizable: true,        // 是否支持缩放

   maximized: false,       // 最大化窗口

   decorations: false,     // 窗口是否装饰边框及导航条

   alwaysOnTop: false,     // 置顶窗口

   fileDropEnabled: false, // 禁止系统拖放

   visible: false          // 隐藏窗口

}

 

/**

* @desc    窗口管理

* @author: YXY  Q:282310962

* @time    2023.07

*/



import { WebviewWindow, appWindow, getAll } from '@tauri-apps/api/window'

import { relaunch, exit } from '@tauri-apps/api/process'

import { emit, listen } from '@tauri-apps/api/event'



import { setWin } from './actions'



// 创建窗口参数配置

export const windowConfig = {

   label: null,            // 窗口唯一label

   title: '',              // 窗口标题

   url: '',                // 路由地址url

   width: 1000,            // 窗口宽度

   height: 640,            // 窗口高度

   minWidth: null,         // 窗口最小宽度

   minHeight: null,        // 窗口最小高度

   x: null,                // 窗口相对于屏幕左侧坐标

   y: null,                // 窗口相对于屏幕顶端坐标

   center: true,           // 窗口居中显示

   resizable: true,        // 是否支持缩放

   maximized: false,       // 最大化窗口

   decorations: false,     // 窗口是否装饰边框及导航条

   alwaysOnTop: false,     // 置顶窗口

   fileDropEnabled: false, // 禁止系统拖放

   visible: false          // 隐藏窗口

}



class Windows {

   constructor() {

       // 主窗口

       this.mainWin = null

   }



   // 创建新窗口

   async createWin(options) {

       console.log('-=-=-=-=-=开始创建窗口')



       const args = Object.assign({}, windowConfig, options)



       // 判断窗口是否存在

       const existWin = getAll().find(w => w.label == args.label)

       if(existWin) {

           console.log('窗口已存在>>', existWin)

           if(existWin.label.indexOf('main') == -1) {

               // 自定义处理...

           }

       }



       // 是否主窗口

       if(args.label.indexOf('main') > -1) {

           console.log('该窗口是主窗口')

           // 自定义处理...

       }



       // 创建窗口对象

       let win = new WebviewWindow(args.label, args)

       // 是否最大化

       if(args.maximized && args.resizable) {

           win.maximize()

       }



       // 窗口创建完毕/失败

       win.once('tauri://created', async() => {

           console.log('window create success!')

           await win?.show()

       })



       win.once('tauri://error', async() => {

           console.log('window create error!')

       })

   }



   // 获取窗口

   getWin(label) {

       return WebviewWindow.getByLabel(label)

   }



   // 获取全部窗口

   getAllWin() {

       return getAll()

   }



   // 开启主进程监听事件

   async listen() {

       console.log('——+——+——+——+——+开始监听窗口')



       // 创建新窗体

       await listen('win-create', (event) => {

           this.createWin(event.payload)

       })



       // 显示窗体

       await listen('win-show', async(event) => {

           if(appWindow.label.indexOf('main') == -1) return

           await appWindow.show()

           await appWindow.unminimize()

           await appWindow.setFocus()

       })



       // 隐藏窗体

       await listen('win-hide', async(event) => {

           if(appWindow.label.indexOf('main') == -1) return

           await appWindow.hide()

       })



       // 关闭窗体

       await listen('win-close', async(event) => {

           await appWindow.close()

       })



       // 退出应用

       await listen('win-exit', async(event) => {

           setWin('logout')

           await exit()

       })



       // ...

   }

}

 

 

整体布局模板

 

提供了入图分栏、垂直、水平三种常见布局。

 

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

 

路由配置

 

/**

* 路由配置

* @author YXY

*/



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)'

   })

   

   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.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

   }

 }

}

 

以上就是tauri+vue3开发跨端后台系统模板的一些分享,希望对大家有所帮助哈~~

 

https://juejin.cn/post/7249347651787243581

 

https://juejin.cn/post/7230558835227066427