首页 > 编程语言 >tauri2.0-admin桌面端后台系统|tauri2+vite5+element-plus管理后台EXE程序

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

时间:2024-10-15 13:23:04浏览次数:6  
标签:vue const admin tauri2 value tauri2.0 后台 import true

原创Tauri2.0+Vue3+ElementPlus客户端通用后台管理系统Tauri2Admin

tauri2-vue3-admin基于最新跨平台框架 Tauri2.0 整合 Vite5+Vue3全家桶 搭建的一款轻量级桌面端后台管理系统模板。封装tauri2多窗口切换管理,提供4种通用布局模板,支持vue-i18n国际化、面包屑导航、多标签快捷路由等功能。

使用技术

  • 编码器: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

功能性

  1. 基于最新跨平台技术栈Tauri2.x、Vite5.x、Vue3 setup、Pinia2、ElementPlus、Vue-I18n、Echarts
  2. 支持国际化中英文/繁体三种语言
  3. 支持动态权限路由、面包屑导航、快捷标签栏缓存路由
  4. tauri2高复用多窗口管理
  5. 提供4种通用布局模板、自由变换风格
  6. 整合常用的表格、表单、列表、图表、编辑器、错误处理等业务场景
  7. 清爽UI界面、轻量级可自由定制模板

项目框架目录

tauri2-vue3admin采用最新跨平台技术 Tauri2.0+Vite5 构建项目模板。

Tauri2.0-Vue3Admin已经更新到我的原创作品集,欢迎去下载使用。

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

入口配置main.js

import { createApp } from 'vue'
import './style.scss'
import App from './App.vue'

// 引入插件配置
import Plugins from './plugins'

// 引入路由/状态管理
import Router from './router'
import Pinia from './pinia'

createApp(App)
.use(Router)
.use(Pinia)
.use(Plugins)
.mount('#app')

tauri2.0-admin通用模板

提供了4种常见的布局模板,也可自由定制化功能模板。

<!-- 布局模板(经典) -->

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

tauri2.0+vue3自定义导航/拖拽窗口

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

tauri设置无边框装饰后,拖拽窗口直接在需要拖拽的元素标签加上 data-tauri-drag-region 属性即可。

tauri2+vue3国际化配置

tauri2-admin使用vue-i18n设置国际化多语言支持。

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-vue3admin动态图表

vue3封装可自适应动态图表,采用 element-resize-detector 插件动态监听DOM尺寸改变。

import { onMounted, onBeforeUnmount, ref } from 'vue'
import * as echarts from 'echarts'
import elementResizeDetectorMaker from 'element-resize-detector'

export function useEcharts(el, options) {
  let chartEl
  let chartRef = ref(null)
  let erd = elementResizeDetectorMaker()

  const resizeHandle = () => {
    chartEl && chartEl.resize()
  }

  onMounted(() => {
    if(el?.value) {
      chartEl = echarts.init(el.value)
      chartEl.setOption(options)
      chartRef.value = chartEl
    }
    erd.listenTo(el.value, resizeHandle)
  })

  onBeforeUnmount(() => {
    chartEl.dispose()
    erd.removeListener(el.value, resizeHandle)
  })

  return chartRef
}

直接通过如下方式调用即可。

import { useEcharts } from '@/hooks/useEcharts'

const visitChartRef = ref(null)
useEcharts(visitChartRef, {
  tooltip: {
    trigger: 'axis',
    appendToBody: true,
  },
  grid: {
    // ...
  },
  xAxis: {
    // ...
  },
  yAxis: {
    type: 'value'
  },
  series: [
    // ...
  ]
})

tauri2-vue3admin标签栏路由/面包屑导航

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

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

  import { useRoutes } from '@/hooks/useRoutes'

  const props = defineProps({
    // 是否显示展开/收缩
    collapseEnable: { type: Boolean, default: true },
  })

  const appstate = appState()
  const { getMatchRoute } = useRoutes()

  const matchRoute = computed(() => getMatchRoute())

  const handleCollapse = () => {
    appstate.config.collapsed = !appstate.config.collapsed
  }
</script>

<template>
  <div class="vu__breadcrumb flexbox">
    <i class="iconfont" :class="appstate.config.collapsed ? 'elec-icon-menuon' : 'elec-icon-menuoff'" @click="handleCollapse"></i>
    <el-breadcrumb separator="/">
      <el-breadcrumb-item v-for="(item, index) in matchRoute" :key="index">
        <router-link v-if="item.path" :to="item.path">{{$t(item?.meta?.title)}}</router-link>
        <template v-else>{{$t(item?.meta?.title)}}</template>
      </el-breadcrumb-item>
    </el-breadcrumb>
  </div>
</template>

Ok,以上就是tauri2.0+vue3实战手撸桌面版后台管理系统的一些知识分享,希望对大家有所帮助!

最后附上几个最新跨平台项目实例

https://www.cnblogs.com/xiaoyan2017/p/18437155

https://www.cnblogs.com/xiaoyan2017/p/18396212

https://www.cnblogs.com/xiaoyan2017/p/18290962

 

标签:vue,const,admin,tauri2,value,tauri2.0,后台,import,true
From: https://www.cnblogs.com/xiaoyan2017/p/18467237

相关文章

  • 如何进入网站后台管理页面
    进入网站后台管理页面通常涉及以下几个步骤:获取访问地址:了解网站后台的访问路径,通常是域名后面加上特定的路径,如 /admin 或 /wp-admin 等。登录凭证:拥有有效的用户名和密码。这些信息通常在网站建立之初就已设定好,或由网站管理员分配。访问后台:在浏览器中输......
  • 请问网站后台登录密码忘记了怎么办
    当您遇到网站后台登录密码忘记的情况时,可以尝试以下几种方法来解决问题:密码找回功能:大多数网站都会提供“忘记密码”或“找回密码”的链接,点击后通常可以通过注册邮箱或手机接收验证码来重置密码。联系管理员:如果您不是网站的所有者或者没有权限使用找回密码的功能,建议联系......
  • 如何通过网站后台修改网站怎样修改网站
    要通过网站后台修改网站内容或设置,通常可以遵循以下步骤:登录后台:打开网站的管理后台URL。输入管理员用户名和密码进行登录。导航到编辑页面:在后台界面中找到需要修改的部分,如文章、页面、产品列表等。选择“编辑”或相应的操作按钮进入具体编辑页面。进行内容编......
  • 如何修改网站后台密码怎么修改网站密码
    修改网站后台密码通常涉及以下几个步骤:登录后台:使用当前的用户名和密码登录到网站的管理后台。找到用户设置:在后台界面中找到“用户”、“管理员”或“账号设置”等相关选项。进入密码修改页面:在用户设置中找到“修改密码”或类似功能的链接或按钮。输入新密......
  • 网站管理员如何登录网站后台管理网站?
    网站管理员登录网站后台通常遵循以下步骤:访问后台登录页面:管理员需要在浏览器地址栏输入特定的URL来访问后台登录页面。这个URL通常是网站主域名加上特定的路径,例如 http://www.example.com/admin 或 http://www.example.com/login。输入用户名和密码:在登录页面上,管......
  • 网站为什么要定期修改后台和FTP密码?
    定期修改后台和FTP密码是保障网站安全的重要措施之一,主要原因包括:降低风险:即使密码已被泄露或存在潜在的安全漏洞,定期更改密码可以减少这些信息被滥用的时间窗口。增强安全性:频繁更换密码能够提高破解难度,使得攻击者更难以通过暴力破解或其他手段获取访问权限。符合安全规范:许......
  • 实战篇:(二)React 创建项目并连接 MySQL 后台的实战教程
    React创建项目并连接MySQL后台的实战教程一、项目概述本篇博客将介绍如何使用React搭建前端项目,并通过Node.js和MySQL实现简单的后台数据连接。通过这个项目,你将掌握从前端到后端数据库的基础开发流程,适合初学者或正在项目实战中的开发者。二、项目准备1.环境......
  • Vue2+ECharts+Mock.js实现前端后台通用管理系统页面
    一、前言  在现代Web开发中,前端框架与数据可视化工具的结合能够显著提升用户体验。本文将介绍如何使用Vue2和ECharts构建一个通用的后台管理系统页面。利用Vue2的组件化特性,可以高效管理应用状态与UI交互,而ECharts则提供多样的图表类型,便于展示数据分析结果。通过整合这两......
  • nbsaas vue3管理后台框架
    nbsaasvue3管理后台框架一、项目概述NbsaasAdminVue是一个基于Vue.js3.0构建的轻量级后台管理系统,结合了现代前端技术栈的最佳实践,旨在帮助开发者快速构建具有高可扩展性和良好用户体验的后台管理系统。该项目拥有简洁的UI设计,强大的功能模块,支持多种自定义配置,......
  • adminPage-vue3依赖 v1.2.0新增组件 DetailsModule说明文档
    adminPage-vue3依赖v1.2.0新增组件DetailsModule说明文档引入思路介绍DetailsModuleAPI汇总属性插槽自定义对象config(array<object\>/object类型)config.list(array<object\>类型)使用基础使用范例config-titleconfig-moduleKeyconfig-listconfig-list-slotNamec......