<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      基于tauri+vue3.x多開窗口|Tauri創(chuàng)建多窗體實(shí)踐

      最近一種在搗鼓 Tauri 集成 Vue3 技術(shù)開發(fā)桌面端應(yīng)用實(shí)踐,tauri 實(shí)現(xiàn)創(chuàng)建多窗口,窗口之間通訊功能。

      開始正文之前,先來了解下 tauri 結(jié)合 vue3.js 快速創(chuàng)建項(xiàng)目。

      tauri 在 github 上star高達(dá)53K+,而且呈快速增長(zhǎng)趨勢(shì)。相比electron構(gòu)建應(yīng)用更具優(yōu)勢(shì)。

      分別用 Tauri 和 Electron 打包測(cè)試一個(gè) todo list 程序。

      Electron打包體積  69  M,Tauri打包體積才只有  7.5 M。

      Tauri 構(gòu)建的桌面應(yīng)用體積遠(yuǎn)遠(yuǎn)比 Electron 構(gòu)建的小得多。因?yàn)樗艞壛梭w積龐大的 Chromium 內(nèi)核和Nodejs,tauri前端集成了 webview,后端使用 Rust。而且 Tauri 構(gòu)建應(yīng)用還提供了諸多初始化程序模板,比如原生 JavaScript、Vue2/3、React、Svelte.js、SvelteKit 等。

      準(zhǔn)備工作

      首先您需要安裝 Rust 及其他系統(tǒng)依賴。

      • "C++ 生成工具" 和 Windows 10 SDK。
      • Tauri 需要 WebView2 才能在 Windows 上呈現(xiàn)網(wǎng)頁內(nèi)容,所以您必須先安裝 WebView2。
      • Rust

      具體操作,請(qǐng)前往 https://tauri.app/zh/v1/guides/getting-started/prerequisites 來按步驟操作。

      • 創(chuàng)建 tauri 初始化項(xiàng)目

      具體的前端框架模板,大家根據(jù)實(shí)際情況選擇。

       npm create tauri-app 

      • 開發(fā)/構(gòu)建打包

       tauri dev  tauri build 

      非常簡(jiǎn)單的幾步就能快速搭建 vue3+tauri 桌面端模板。接下來就能順利的開發(fā)了。

      tauri 也提供了如下幾種常用創(chuàng)建多窗口的方法。

      • tauri.conf.json
      {
        "tauri": {
          "windows": [
            {
              "label": "external",
              "title": "Tauri App",
              "url": "https://tauri.app"
            },
            {
              "label": "local",
              "title": "Tauri",
              "url": "home.html"
            }
          ]
        }
      }
      • src-tauri/src/main.rs
      tauri::Builder::default()
        .setup(|app| {
          let docs_window = tauri::WindowBuilder::new(
            app,
            "external", /* the unique window label */
            tauri::WindowUrl::External("https://tauri.app/".parse().unwrap())
          ).build()?;
          let local_window = tauri::WindowBuilder::new(
            app,
            "local",
            tauri::WindowUrl::App("index.html".into())
          ).build()?;
          Ok(())
      })
      • 通過前端 JS 創(chuàng)建窗口。
      import { WebviewWindow } from '@tauri-apps/api/window'
      const webview = new WebviewWindow('main_win', {
        url: '/home',
      })
      
      webview.once('tauri://created', function () {
        // webview window successfully created
      })
      webview.once('tauri://error', function (e) {
        // an error happened creating the webview window
      })

      具體詳細(xì)的介紹,大家可以去官網(wǎng)查看,文檔都有非常詳細(xì)的講解。

      https://tauri.app/zh/v1/guides/features/multiwindow

      上面介紹的方法比較適用于一些簡(jiǎn)單的窗口,對(duì)于一些復(fù)雜多開窗口,還得封裝一個(gè)窗口創(chuàng)建器,直接通過傳入?yún)?shù)快速生成窗體。

      createWin({
          label: 'Home',
          title: '主頁',
          url: '/home',
          width: 800,
          height: 600,
      })

      新建一個(gè) windows 文件夾,用來封裝窗口及調(diào)用窗口。

      /**
       * @desc    窗口容器
       * @author: YXY  Q:282310962
       * @time    2022.10
       */
      
      import { WebviewWindow, appWindow, getAll, getCurrent } 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'
      
      // 系統(tǒng)參數(shù)配置
      export const windowConfig = {
          label: null,            // 窗口唯一label
          title: '',              // 窗口標(biāo)題
          url: '',                // 路由地址url
          width: 900,             // 窗口寬度
          height: 640,            // 窗口高度
          minWidth: null,         // 窗口最小寬度
          minHeight: null,        // 窗口最小高度
          x: null,                // 窗口相對(duì)于屏幕左側(cè)坐標(biāo)
          y: null,                // 窗口相對(duì)于屏幕頂端坐標(biāo)
          center: true,           // 窗口居中顯示
          resizable: true,        // 是否支持縮放
          maximized: false,       // 最大化窗口
          decorations: false,     // 窗口是否無邊框及導(dǎo)航條
          alwaysOnTop: false,     // 置頂窗口
      }
      
      class Windows {
          constructor() {
              this.mainWin = null
          }
      
          // 獲取窗口
          getWin(label) {
              return WebviewWindow.getByLabel(label)
          }
      
          // 獲取全部窗口
          getAllWin() {
              return getAll()
          }
      
          // 創(chuàng)建新窗口
          async createWin(options) {
              const args = Object.assign({}, windowConfig, options)
      
              // 判斷窗口是否存在
              const existWin = getAll().find(w => w.label == args.label)
              if(existWin) {
                  if(existWin.label.indexOf('main') == -1) {
                      await existWin?.unminimize()
                      await existWin?.setFocus()
                      return
                  }
                  await existWin?.close()
              }
      
              // 創(chuàng)建窗口對(duì)象
              let win = new WebviewWindow(args.label, args)
              
              // 是否最大化
              if(args.maximized && args.resizable) {
                  win.maximize()
              }
      
              // 窗口創(chuàng)建完畢/失敗
              win.once('tauri://created', async() => {
                  console.log('window create success!')
                  ...
              })
      
              win.once('tauri://error', async() => {
                  console.log('window create error!')
              })
          }
      
          // 開啟主進(jìn)程監(jiān)聽事件
          async listen() {
              // 創(chuàng)建新窗體
              await listen('win-create', (event) => {
                  console.log(event)
                  this.createWin(JSON.parse(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()
              })
      
              // 退出應(yīng)用
              await listen('win-exit', async(event) => {
                  setWin('logout')
                  await exit()
              })
      
              // 重啟應(yīng)用
              await listen('win-relaunch', async(event) => {
                  await relaunch()
              })
      
              // 主/渲染進(jìn)程傳參
              await listen('win-setdata', async(event) => {
                  await emit('win-postdata', JSON.parse(event.payload))
              })
          }
      }
      
      export default Windows

      actions.js進(jìn)行一些調(diào)用處理。

      /**
       * 處理渲染器進(jìn)程到主進(jìn)程的異步通信
       */
      
      import { WebviewWindow } from '@tauri-apps/api/window'
      import { emit } from '@tauri-apps/api/event'
      
      /**
       * @desc 創(chuàng)建新窗口
       */
      export async function createWin(args) {
          await emit('win-create', args)
      }
      
      /**
       * @desc 獲取窗口
       * @param args {string}
       */
      export async function getWin(label) {
          return await WebviewWindow.getByLabel(label)
      }
      
      /**
       * @desc 設(shè)置窗口
       * @param type {string} 'show'|'hide'|'close'|'min'|'max'|'max2min'|'exit'|'relaunch'
       */
      export async function setWin(type) {
          await emit('win-' + type)
      }
      
      /**
       * @desc 登錄窗口
       */
      export async function loginWin() {
          await createWin({
              label: 'Login',
              title: '登錄',
              url: '/login',
              width: 320,
              height: 420,
              resizable: false,
              alwaysOnTop: true,
          })
      }
      
      // ...

      在需要調(diào)用創(chuàng)建窗口的.vue頁面,引入actions.js文件。

       import { loginWin, createWin } from '@/windows/actions' 

      const createManageWin = async() => {
          createWin({
              label: 'Manage',
              title: '管理頁面',
              url: '/manage',
              width: 600,
              height: 450,
              minWidth: 300,
              minHeight: 200
          })
      }
      
      const createAboutWin = async() => {
          createWin({
              label: 'About',
              title: '關(guān)于頁面',
              url: '/about',
              width: 500,
              height: 500,
              resizable: false,
              alwaysOnTop: true
          })
      }

      一些注意點(diǎn)

      • 創(chuàng)建系統(tǒng)托盤圖標(biāo)

      use tauri::{
          AppHandle, Manager, 
          CustomMenuItem, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem, SystemTraySubmenu
      };
      
      // 托盤菜單
      pub fn menu() -> SystemTray {
          let quit = CustomMenuItem::new("quit".to_string(), "Quit");
          let show = CustomMenuItem::new("show".to_string(), "Show");
          let hide = CustomMenuItem::new("hide".to_string(), "Hide");
          let change_ico = CustomMenuItem::new("change_ico".to_string(), "Change Icon");
          let tray_menu = SystemTrayMenu::new()
              .add_submenu(SystemTraySubmenu::new(
                  "Language", // 語言菜單
                  SystemTrayMenu::new()
                      .add_item(CustomMenuItem::new("lang_english".to_string(), "English"))
                      .add_item(CustomMenuItem::new("lang_zh_CN".to_string(), "簡(jiǎn)體中文"))
                      .add_item(CustomMenuItem::new("lang_zh_HK".to_string(), "繁體中文")),
              ))
              .add_native_item(SystemTrayMenuItem::Separator) // 分割線
              .add_item(change_ico)
              .add_native_item(SystemTrayMenuItem::Separator)
              .add_item(hide)
              .add_item(show)
              .add_native_item(SystemTrayMenuItem::Separator)
              .add_item(quit);
      
          SystemTray::new().with_menu(tray_menu)
      }
      
      // 托盤事件
      pub fn handler(app: &AppHandle, event: SystemTrayEvent) {
          match event {
              SystemTrayEvent::LeftClick {
                  position: _,
                  size: _,
                  ..
              } => {
                  println!("點(diǎn)擊左鍵");
              }
              SystemTrayEvent::RightClick {
                  position: _,
                  size: _,
                  ..
              } => {
                  println!("點(diǎn)擊右鍵");
              }
              SystemTrayEvent::DoubleClick {
                  position: _,
                  size: _,
                  ..
              } => {
                  println!("雙擊");
              }
              SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
                  "change_ico" => { // 更新托盤圖標(biāo)
                      app.tray_handle()
                          .set_icon(tauri::Icon::Raw(
                              include_bytes!("../icons/new.png").to_vec()
                          ))
                          .unwrap();
                  }
                  lang if lang.contains("lang_") => { // 選擇語言,匹配 id 前綴包含 `lang_` 的事件
                      Lang::new(
                          app,
                          id, // 點(diǎn)擊菜單的 id
                          vec![
                              Lang {
                                  name: "English",
                                  id: "lang_english",
                              },
                              Lang {
                                  name: "繁體中文",
                                  id: "lang_zh_HK",
                              },
                              Lang {
                                  name: "簡(jiǎn)體中文",
                                  id: "lang_zh_CN",
                              },
                          ],
                      );
                  }
                  "hide" => {
                      // let window = app.get_window("main").unwrap();
                      // window.show().unwrap();
                      println!("點(diǎn)擊隱藏");
                  }
                  "show" => {
                      println!("點(diǎn)擊顯示");
                  }
                  "quit" => {
                      println!("點(diǎn)擊退出");
                      std::process::exit(0);
                  }
                  _ => {}
              },
              _ => {}
          }
      }
      
      struct Lang<'a> {
          name: &'a str,
          id: &'a str,
      }
      
      impl Lang<'static> {
          fn new(app: &AppHandle, id: String, langs: Vec<Lang>) {
              // 獲取點(diǎn)擊的菜單項(xiàng)
              langs.iter().for_each(|lang| {
                  let handle = app.tray_handle().get_item(lang.id);
                  if lang.id.to_string() == id.as_str() {
                      // 設(shè)置菜單名稱
                      handle.set_title(format!("  {}", lang.name)).unwrap();
                      // 還可以使用 `set_selected`、`set_enabled` 和 `set_native_image`(僅限 macOS)
                      handle.set_selected(true).unwrap();
                  } else {
                      handle.set_title(lang.name).unwrap();
                      handle.set_selected(false).unwrap();
                  }
              });
          }
      }

      創(chuàng)建托盤圖標(biāo),默認(rèn)圖標(biāo)文件在src-tauri/icons目錄下。如果想使用自定義的.ico圖標(biāo),可通過tauri.cong.json文件配置。

      "systemTray": {
          "iconPath": "icons/tray.ico",
          "iconAsTemplate": true,
          "menuOnLeftClick": false
      }

      如果setIcon報(bào)錯(cuò),則需要在 src-tauri/src/Cargo.toml 中配置 icon-icoicon-png

      • tauri 配置自定義拖拽區(qū)域。

      當(dāng)創(chuàng)建窗口的時(shí)候配置了 decorations: false  則會(huì)不顯示窗口邊框及頂部導(dǎo)航欄。

      此時(shí)在需要拖動(dòng)元素上加一個(gè)  data-tauri-drag-region 屬性,即可實(shí)現(xiàn)自定義區(qū)域拖動(dòng)窗口功能。這個(gè)功能有些類似 electron 中自定義拖拽 -webkit-app-region: drag

      不過點(diǎn)擊窗口右鍵,會(huì)出現(xiàn)系統(tǒng)菜單。這樣顯得應(yīng)用不夠原生,可以簡(jiǎn)單的通過禁用右鍵菜單來屏蔽功能。

      export function disableWinMenu() {
          document.addEventListener('contextmenu', e => e.preventDefault())
      }
      disableWinMenu()

      好了,基于 tauri+vue3 構(gòu)建多窗口桌面應(yīng)用就分享到這里。希望對(duì)大家有丟丟幫助哈~~ ??

      目前最新版Tauri2.0+Vite5跨平臺(tái)實(shí)戰(zhàn)項(xiàng)目已經(jīng)同步到我的原創(chuàng)作品集。

      Tauri2.0-Vue3OS桌面端os平臺(tái)|tauri2+vite6+arco電腦版OS管理系統(tǒng)

      Tauri2.0+Vite5聊天室|vue3+tauri2+element-plus仿微信|tauri聊天應(yīng)用

      tauri2.0-admin桌面端后臺(tái)系統(tǒng)|Tauri2+Vite5+ElementPlus管理后臺(tái)EXE程序

      最后附上三個(gè)最新Electron+Vue3原創(chuàng)重磅跨平臺(tái)實(shí)例。

      Electron32-ViteOS桌面版os系統(tǒng)|vue3+electron+arco客戶端OS管理模板

      Vite5+Electron聊天室|electron31跨平臺(tái)仿微信EXE客戶端|vue3聊天程序

      Electron31-Vue3Admin管理系統(tǒng)|vite5+electron+pinia桌面端后臺(tái)Exe

       

      posted @ 2022-10-21 00:13  xiaoyan2017  閱讀(7459)  評(píng)論(5)    收藏  舉報(bào)
      友情鏈接: UP主小店B站
      主站蜘蛛池模板: 国产一区二区三区黄色片| 人妻中文字幕亚洲一区| 久9re热视频这里只有精品免费| 亚洲av成人在线一区| 人人妻人人妻人人片av| 国产亚洲精品久久77777| 四虎国产精品久久免费精品| 好吊妞| 99精品国产综合久久久久五月天| 天堂av在线一区二区| 欧美亚洲综合成人A∨在线| 澄城县| 另类 专区 欧美 制服| 久久精品免视看国产成人| 国产成a人片在线观看视频下载| 白嫩人妻精品一二三四区| 午夜男女爽爽影院在线| 久久精品夜夜夜夜夜久久| 欧美大胆老熟妇乱子伦视频| 亚洲性日韩一区二区三区| 国产精品国产三级国产试看| xxxxbbbb欧美残疾人| 成人亚洲狠狠一二三四区| 18禁无遮挡啪啪无码网站| 亚洲色一色噜一噜噜噜| 国产精品伊人久久综合网| 人妻中文字幕在线视频无码| 中文字幕在线国产精品| 天干天干啦夜天干天2017| 精品国产成人国产在线观看| 午夜成人鲁丝片午夜精品| 国产自拍偷拍视频在线观看| 亚洲精品二区在线播放| 又黄又爽又色的免费网站| 久久精品国产88精品久久| 亚洲成av人片在www鸭子| 在线播放无码后入内射少妇| 久99久热这里只有精品| 中文字幕日韩有码一区| 狠狠婷婷综合久久久久久| 亚洲精品国模一区二区|