x***@126.com
x***@126.com
  • 发布:2024-10-17 21:18
  • 更新:2024-10-17 21:18
  • 阅读:276

vue3.5+tauri v2桌面版后台管理系统|vite5+tauri2+element-plus客户端后台模板

分类:HTML5+

经过大半个月高强度实战开发,又一款原创跨平台新作tauri2.0+vue3+pinia2+elementPlus+mockjs电脑端通用权限后台管理系统,正式结束了。实现4种通用布局模板,支持vue-i18n国际化、面包屑导航、tab标签路由等功能。

tauri2.0-vue3admin桌面端管理系统|tauri2+vite5+element-plus后台EXE程序

img

img

使用技术

  • 开发工具:VScode
  • 技术框架:tauri2.0+vite^5.4.8+vue^3.5.11+vue-router^4.4.5
  • 状态管理:pinia^2.2.4
  • 存储服务:pinia-plugin-persistedstate^4.1.1
  • 组件库:element-plus^2.8.5
  • 图表组件:echarts^5.5.1
  • 国际化:vue-i18n^10.0.4
  • 富文本编辑器:@vueup/vue-quill^1.2.0
  • md编辑器:md-editor-v3^4.20.3
  • 模拟数据:mockjs^1.1.0
  • 预处理样式:sass^1.79.4

img

img

目前该项目Tauri2-Vue3Admin已经同步发布到我的原创作品集。

https://gf.bilibili.com/item/detail/1107226011

项目结构

img

img

img

img

tauri2-admin后台布局模板

img

<script setup>  
  import { appState } from '@/pinia/modules/app'  

  import Toolbar from '@/layouts/components/Toolbar.vue'  
  import Sidebar from '@/layouts/components/sidebar/index.vue'  
  import Menus from '@/layouts/components/menus/index.vue'  
  import Breadcrumb from '@/layouts/components/Breadcrumb.vue'  
  import Tabview from '@/layouts/components/Tabview.vue'  
  import Main from '@/layouts/components/Main.vue'  

  const appstate = appState()  
</script>  

<template>  
  <div class="vuadmin__layout flexbox flex-col">  
    <Toolbar />  

    <div class="vuadmin__layout-body flex1 flexbox">  
      <!-- 侧边栏 -->  
      <div class="vuadmin__layout-sidebar">  
        <Sidebar />  
      </div>  

      <!-- 菜单栏 -->  
      <div class="vuadmin__layout-menus" :class="{'hidden': appstate.config.collapsed}">  
        <el-scrollbar>  
          <Menus :rootRouteEnable="false" />  
        </el-scrollbar>  
      </div>  

      <!-- 右侧主内容区 -->  
      <div class="vuadmin__layout-main flex1 flexbox flex-col">  
        <!-- 面包屑导航 -->  
        <Breadcrumb v-if="appstate.config.breadcrumb" />  

        <!-- 标签页 -->  
        <Tabview v-if="appstate.config.tabview" />  

        <!-- 内容区 -->  
        <Main />  
      </div>  
    </div>  
  </div>  
</template>

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

tauri2-admin国际化配置

img

img

import { createI18n } from 'vue-i18n'  
import { appState } 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 appstate = appState()  
  const lang = appstate.lang || langVal  
  appstate.setLang(lang)  

  const i18n = createI18n({  
    legacy: false,  
    locale: lang,  
    messages: {  
      'en': enUS,  
      'zh-CN': zhCN,  
      'zh-TW': zhTW  
    }  
  })  

  app.use(i18n)  
}

tauri2-admin实现自定义导航栏

img

<script setup>  
  import { ref, markRaw } from 'vue'  
  import { ElMessageBox } from 'element-plus'  
  import { QuestionFilled, SwitchButton } from '@element-plus/icons-vue'  
  import { getCurrentWindow } from '@tauri-apps/api/window'  
  import { listen } from '@tauri-apps/api/event'  
  import { exit } from '@tauri-apps/plugin-process'  

  import { isTrue } from '@/utils'  
  import { authState } from '@/pinia/modules/auth'  

  const authstate = authState()  

  const props = defineProps({  
    color: String,  
    // 窗口是否可最小化  
    minimizable: {type: [Boolean, String], default: true},  
    // 窗口是否可最大化  
    maximizable: {type: [Boolean, String], default: true},  
    // 窗口是否可关闭  
    closable: {type: [Boolean, String], default: true},  
    // 层级  
    zIndex: {type: [Number, String], default: 2024},  
  })  

  const hasMaximized = ref(false)  
  const isResizable = ref(true)  
  const isMaximizable = ref(true)  

  // 用户是否可以手动调整窗口大小  
  getCurrentWindow().isResizable().then(res => {  
    isResizable.value = res  
  })  
  // 窗口是否可以最大化  
  getCurrentWindow().isMaximizable().then(res => {  
    isMaximizable.value = res  
  })  
  // 初始监听窗口是否最大化  
  getCurrentWindow().isMaximized().then(res => {  
    hasMaximized.value = res  
  })  
  // 实时监听窗口是否最大化  
  listen('tauri://resize', async() => {  
    hasMaximized.value = await getCurrentWindow().isMaximized()  
  })  

  // 最小化  
  const handleWinMin = async() => {  
    await getCurrentWindow().minimize()  
  }  
  // 最大化/还原  
  const handleWinToggle = async() => {  
    await getCurrentWindow().toggleMaximize()  
  }  
  // 关闭  
  const handleWinClose = async() => {  
    const isMajor = getCurrentWindow().label.indexOf('main') > -1  
    if(isMajor) {  
      ElMessageBox.confirm('是否最小化到系统托盘,不退出程序?', '提示', {  
        type: 'warning',  
        icon: markRaw(QuestionFilled),  
        confirmButtonText: '残忍退出',  
        cancelButtonText: '最小化到托盘',  
        customStyle: {'width': '300px'},  
        draggable: true,  
        roundButton: true,  
        center: true,  
        buttonSize: 'small',  
        distinguishCancelAndClose: true,  
      }).then(async() => {  
        authstate.logout()  
        await exit()  
      }).catch(async(action) => {  
        if(action === 'cancel') {  
          await getCurrentWindow().hide()  
        }  
      })  
    }else {  
      await getCurrentWindow().close()  
    }  
  }  
</script>  

<template>  
  <div class="ev__winbtns flexbox flex-alignc vu__drag" :style="{'z-index': zIndex}">  
    <div class="ev__winbtns-actions flexbox flex-alignc vu__undrag" :style="{'color': color}">  
      <a v-if="isTrue(minimizable)" class="wbtn min" title="最小化" @click="handleWinMin"><i class="wicon iconfont elec-icon-min"></i></a>  
      <a v-if="isTrue(maximizable)" class="wbtn toggle" :title="hasMaximized ? '向下还原' : '最大化'" @click="handleWinToggle">  
        <i class="wicon iconfont" :class="hasMaximized ? 'elec-icon-restore' : 'elec-icon-max'"></i>  
      </a>  
      <a v-if="isTrue(closable)" class="wbtn close" title="关闭" @click="handleWinClose"><i class="wicon iconfont elec-icon-quit"></i></a>  
    </div>  
  </div>  
</template>  

<style lang="scss" scoped>  
  @import './index.scss';  
</style>

tauri2-vue3admin自定义标签栏路由

img

img

<template>  
  <div class="vu__tabview">  
    <el-tabs  
      v-model="activeTab"  
      class="vu__tabview-tabs"  
      @tab-change="changeTabs"  
      @tab-remove="removeTab"  
    >  
      <el-tab-pane  
        v-for="(item, index) in tabList"  
        :key="index"  
        :name="item.path"  
        :closable="!item?.meta?.isAffix"  
      >  
        <template #label>  
          <el-dropdown ref="dropdownRef" trigger="contextmenu" :id="item.path" @visible-change="handleDropdownChange($event, item.path)" @command="handleDropdownCommand($event, item)">  
            <span class="vu__tabview-tabs__label">  
              <span>{{$t(item?.meta?.title)}}</span>  
            </span>  
            <template #dropdown>  
              <el-dropdown-menu>  
                <el-dropdown-item command="refresh" :icon="Refresh">{{$t('tabview__contextmenu-refresh')}}</el-dropdown-item>  
                <el-dropdown-item command="close" :icon="Close" :disabled="item.meta.isAffix">{{$t('tabview__contextmenu-close')}}</el-dropdown-item>  
                <el-dropdown-item command="closeOther" :icon="Switch">{{$t('tabview__contextmenu-closeother')}}</el-dropdown-item>  
                <el-dropdown-item command="closeLeft" :icon="DArrowLeft">{{$t('tabview__contextmenu-closeleft')}}</el-dropdown-item>  
                <el-dropdown-item command="closeRight" :icon="DArrowRight">{{$t('tabview__contextmenu-closeright')}}</el-dropdown-item>  
                <el-dropdown-item command="closeAll" :icon="CircleCloseFilled">{{$t('tabview__contextmenu-closeall')}}</el-dropdown-item>  
              </el-dropdown-menu>  
            </template>  
          </el-dropdown>  
        </template>  
      </el-tab-pane>  
    </el-tabs>  
  </div>  
</template>

img

tauri2+vue3实现自定义托盘右键菜单功能。

img

End,以上就是tauri2+vue3+pinia2实战开发桌面版后台管理系统模板的一些知识分享。

作者:xiaoyan2017
链接: https://segmentfault.com/a/1190000045381943
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 关注 分享

要回复文章请先登录注册