tauri-vue 3-adminバックグラウンド管理exeプログラムテンプレート

tauri-vue 3-adminバックグラウンド管理exeプログラムテンプレート

Tauri+Vue3+Pinia2+Veplusクロスデスクトップ共通バックグラウンド管理システムアプリケーションテンプレートTauriAdminに基づいています。

最后更新 2023/07/27 22:14
前端加油栈
预计阅读 8 分钟
分类
フロント·エンド
标签
Vue Tauri

プレゼンテーション:プレゼンテーション

基于tauri+vue3+pinia2+veplus跨平台、桌面端通用后台管理系统应用模板TauriAdmin

tauri-adminはクロスエンド技術Tauri Rustを使用してvite 4.xと統合し、コンピュータサイドのバックグラウンドシステムプログラムexeテンプレートを構築します。

マルチオープンフォーム管理、国際化多言語、ルート認証検証/ルートキャッシュ、常用業務機能モジュールをサポートする。

テクノロジースタック

  • エディタ:VScode
  • 技術フレームワーク:tauri+vite4+vue3+pinia2+vue-router
  • UIコンポーネントライブラリve-plus vue3コンピュータ側UIコンポーネントライブラリに基づく
  • スタイル処理sass ^1.63.6
  • チャート·コンポーネントecharts ^5.4.2
  • 国際化スキーム:Vue-i 18 n^9.2.2
  • エディタコンポーネントwanged ^4.7.15
  • ローカルキャッシュpinia-plugin-peredstate ^3.1.0

プロジェクトには3つの一般的なレイアウトテンプレートスタイルが組み込まれており、好みに応じて切り替えたり、好みのテンプレートをカスタマイズしたりできます。

プロジェクトビルドディレクトリ

プロジェクト全体はTauri-cliの足場に基づいてVue3プロジェクトを構築しています。プロジェクトテンプレートと複数のウィンドウの作成に興味がある場合は、以前の共有記事を参照してください。

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

Tauri Vue3は複数のウィンドウを開く。

tauriマルチウィンドウカプセル化管理用のindex.jsファイルをmultwinsディレクトリに作成します。

// 创建窗口配置
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, // 隐藏窗口
};

tauriが提供するWebviewWindowメソッドで新しいウィンドウインスタンスを作成します。ラベルはウィンドウの一意の識別子であるため、メインウィンドウに切り替える必要がある場合は、ラベルにmainキーワードを含める必要があります。mainキーワードがあるかどうかを検索してメインウィンドウかを判断します。

/**
 * @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();
    });

    // ...
  }
}

メインテンプレートレイアウト。

プロジェクトには、一般的に使用される3つのテンプレートレイアウトスタイルが組み込まれています。それぞれ伝統的なセクション、メニュー式、水平メニュー式である。

<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">
        <component :is="LayoutConfig[config.layout]" />
    </div>
</template>

ルーティング設定

tauriプロジェクトではルートジャンプ管理にvue-routerを使用している.

/**
 * 路由配置 Router
 * @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;

Piniaの管理

現在、Vue3プロジェクトは状態管理にPiniaを推奨していますが、もちろんVuexはまだ使用できます。

/**
 * 状态管理配置 Pinia
 * @author YXY
 */

import { createPinia } from "pinia";
// 引入pinia本地持久化存储
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";

const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);

export default pinia;

ローカル永続ストレージはpiniaプラグインpinia-plugin-persistedstateを使用して実装されます。

vue-i18n国際化ソリューション

tauri-adminは英語/繁体字の3言語構成をサポートします。

/**
 * 国际化配置 VueI18n
 * @author YXY
 */

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

OK、これはTauri+Vue3+Piniaのクライアントサイドバックグラウンド管理システムのテンプレートインスタンスの共有です。

Keep Exploring

延伸阅读

更多文章
同标签 2024/11/06

なぜ私のブログはBlazorに戻るのか?

ブログサイトの開発は苦労し、MVC、Vue、Goなどの10近くのバージョンを試してきましたが、Blazorに戻り、静的SSRを使用して、速度が急上昇し、正常にオンラインになりました。

继续阅读
同标签 2024/01/13

グレース!もう一つの. NET Coreオープンソースフレームワークプロジェクト:フレームワーク

ABP vNextネイティブバージョン、Furionバージョン、フロントエンドバックグラウンドアクセスRuoYi Vue 3.0、組み込みRBAC権利管理、最新のコミュニティモジュールをサポートし、ユーザーエクスペリエンスから始まる. NET 8 Webオープンソースフレームワークのセット。

继续阅读
同标签 2023/10/16

NET Toolbox:トップ10のツールカテゴリと73のリアルタイムオンラインガジェットを探索するオープンソースの無料の純粋なフロントエンドツールサイト。

Dotnet Toolboxは純粋なフロントエンド、オープンソース、無料のツールサイトです。週末にはオープンソースプロジェクトit-toolsを参照して、インターフェイステキストを中国語化し、サイトを再デプロイしました。このサイトには10のツールカテゴリがあり、73のリアルタイムオンラインガジェットがあります。Vue3で開発されたDotnetツールボックスにはユニークな機能があります。この記事では、これらの機能のいくつかを詳しく説明し、独自のツールサイトをデプロイする方法を簡単に共有します。ツールのウェブサイトに興味がある場合は、Dotnetツールボックスをチェックしてください。

继续阅读