教程地址:https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from=333.788.player.switch&vd_source=707ec8983cc32e6e065d5496a7f79ee6
官方指引:https://tauri.app/zh-cn/start/
目前Tauri2的教程視頻不多,我按照Tauri1的教程來學習,轉成Tauri2
一、Tauri2 安裝
- 安裝win系統依賴,Microsoft C++
https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools/
2. 若沒有的,要安裝WebView2
下載并安裝“常青獨立安裝程序(Evergreen Bootstrapper)
https://developer.microsoft.com/zh-cn/microsoft-edge/webview2/?form=MA13LH#download
3. 安裝Rust
https://www.rust-lang.org/zh-CN/tools/install
打開,選擇1,進行默認安裝
安裝完成后,輸入 rustc --version和cargo --version來驗證
配置cargo環境變量
PATH里,加入%USERPROFILE%.cargo\bin
- 安裝nodejs
https://nodejs.org/zh-cn
驗證是否安裝成功:
node -v
npm -v
nodejs環境變量配置
Path中輸入nodejs的地址,比如C:\Program Files\nodejs\
- 安裝Android,若要導出Android App的話
下載Android Studio
https://developer.android.com/studio?hl=zh-cn
確保安裝了以下內容
Android SDK Platform
Android SDK Platform-Tools
NDK (Side by side)
Android SDK Build-Tools
Android SDK Command-line Tools
配置 ANDROID_HOME 和 NDK_HOME 環境變量
Path中添加
%ANDROID_HOME%\platform-tools
%ANDROID_HOME%\tools
%ANDROID_HOME%\tools\bin
%NDK_HOME%
輸入adb --version 驗證
二、建立工程
- 在文件夾下,放入.npmrc文件,幫助鏡像代理
registry=https://registry.npmmirror.com/
disturl=https://registry.npmmirror.com/-/binary/node
electron_mirror=https://npmmirror.com/mirrors/electron/
electron-builder-binaries_mirror=https://registry.npmmirror.com/-/binary/electron-builder-binaries/
- 進入cmd,輸入
npm create tauri-app@latest
- 安裝配置過程
- 填寫項目名,選擇前端代碼
- 下載完畢,用vscode打開
- 拷貝.npmrc
- 執行npm i 安裝插件
- 執行npm run tauri dev
三、工程介紹
-
各目錄的說明
tauri-app/
├── src/ # 前端源代碼(Vue/React/Svelte 等)
├── src-tauri/ # Tauri 后端(Rust 代碼)
├── public/ # 靜態資源(圖片、字體等)
├── node_modules/ # 前端依賴
├── target/ # Rust 編譯輸出(自動生成)
├── dist/ # 前端構建輸出(自動生成)
├── package.json # 前端項目配置
├── vite.config.js # Vite 配置
└── index.html # 前端入口 HTML -
tauri.conf.json,用于配置窗口信息
四、頁面調用rust方法
https://tauri.app/zh-cn/develop/calling-rust/
- 調用rust函數
- 前端:
import { invoke } from "@tauri-apps/api/core"; //獲取接口函數 invoke// 通過異步的方式調用greet函數,并傳遞參數,參數以鍵值對傳遞
async function greet() {// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/greetMsg.value = await invoke("greet", { name: name.value });
}
- Rust端:
#[tauri::command]
fn greet(name: &str) -> String {format!("Hello, {}! You've been greeted from Rust!", name)
}#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {tauri::Builder::default().plugin(tauri_plugin_opener::init()).invoke_handler(tauri::generate_handler![greet]) // 綁定greet函數.run(tauri::generate_context!()).expect("error while running tauri application");
}
- 同步的方式
- 前端
invoke('login', { user: 'tauri', password: '0j4rijw8=' }).then((message) => console.log(message)).catch((error) => console.error(error));
- rust端
#[tauri::command]
fn login(user: String, password: String) -> Result<String, String> {if user == "tauri" && password == "tauri" {// resolveOk("logged_in".to_string())} else {// rejectErr("invalid credentials".to_string())}
}
五、事件系統(雙工消息)
- 前端發送
- 前端emit事件,是更簡單的通訊方式,沒有返回值;
import { emit } from '@tauri-apps/api/event';
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';// emit(eventName, payload)
emit('file-selected', '/path/to/file'); //全局發送const appWebview = getCurrentWebviewWindow();
appWebview.emit('route-changed', { url: window.location.href }); //指定窗口發送
- 觸發特定監聽事件的emitTo發送
import { emitTo } from '@tauri-apps/api/event';
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';// emitTo(webviewLabel, eventName, payload)
emitTo('settings', 'settings-update-requested', {key: 'notification',value: 'all',
});const appWebview = getCurrentWebviewWindow();
appWebview.emitTo('editor', 'file-changed', {path: '/path/to/file',contents: 'file contents',
});
- Rust接收
- 全局接收
use tauri::Manager;fn main() {tauri::Builder::default().setup(|app| {// 監聽全局事件app.listen_global("global-event", |event| {println!("Received global event: {:?}", event.payload());// 可解析數據(需 serde)if let Some(payload) = event.payload() {println!("Parsed payload: {}", payload);}});Ok(())}).run(tauri::generate_context!()).expect("Failed to run Tauri");
}
- 特定窗口接收
use tauri::Window;fn main() {tauri::Builder::default().setup(|app| {// 獲取目標窗口(假設標簽為 "secondary")let secondary_window = app.get_window("secondary").unwrap();secondary_window.listen("window-specific-event", |event| {println!("Received window-specific event: {:?}", event.payload());});Ok(())}).run(tauri::generate_context!()).expect("Failed to run Tauri");
}
emit有全局發送與特定窗口發送,還有emitTo的寫法
- rust端發送
- 全局事件
use tauri::Manager;fn main() {tauri::Builder::default().setup(|app| {// 發送全局事件(所有前端窗口都能接收)app.emit_all("rust-to-frontend", "Hello from Rust").unwrap();Ok(())}).run(tauri::generate_context!()).expect("Failed to run Tauri");
}
- 定向窗口發送
use tauri::Window;fn main() {tauri::Builder::default().setup(|app| {// 獲取指定窗口(假設窗口標簽為 "main")let main_window = app.get_window("main").unwrap();// 發送到特定窗口main_window.emit("rust-to-specific-window", "Data for main window").unwrap();Ok(())}).run(tauri::generate_context!()).expect("Failed to run Tauri");
}
- 發送復雜數據
use serde::Serialize;#[derive(Serialize)]
struct CustomData {message: String,count: i32,
}fn main() {tauri::Builder::default().setup(|app| {let data = CustomData {message: "Dynamic data".into(),count: 42,};app.emit_all("structured-event", &data).unwrap();Ok(())}).run(tauri::generate_context!()).expect("Failed to run Tauri");
}
- 前端監聽事件
- 全局監聽
import { listen } from '@tauri-apps/api/event';
import { onMounted } from 'vue';onMounted(() => {// 監聽全局事件listen('rust-to-frontend', (event) => {console.log('Received:', event.payload); // 輸出: "Hello from Rust"});
});
- 定向窗口監聽
import { getCurrent } from '@tauri-apps/api/window';
import { onMounted } from 'vue';const currentWindow = getCurrent();onMounted(() => {// 監聽當前窗口的事件currentWindow.listen('rust-to-specific-window', (event) => {console.log('Window-specific data:', event.payload);});
});
- 監聽Json數據
import { listen } from '@tauri-apps/api/event';listen('structured-event', (event) => {console.log('Message:', event.payload.message); // "Dynamic data"console.log('Count:', event.payload.count); // 42
});
六、Http請求
使用http請求,需要先配置tarui.conf.json,把能訪問的網址加入白名單
此舉讓軟件安全性提高很多,對比electron,就很有優勢
七、文件操作
- tauri需要先配置tarui.conf.json,包括文件的操作權限和操作目錄
- 前端才能操作文件,但是前端沒有絕對目錄的操作能力;想操作絕對目錄,需要用rust編寫
- 另外tarui要配置下資源目錄,這樣打包的時候,資源目錄才會打包在一起
- 通過引入
import { readBinaryFile, BaseDirectory } from '@tauri-apps/api/fs';
實現文件的操作
在一代api里有相關資料,在二代的插件里也有相關資料
https://tauri.app/zh-cn/plugin/file-system/
八、本地文件的Url獲取
- 需要進行安全策略配置,在tauri.conf.json中,配置安全策略的頭格式
- 需要配置允許的目錄
- 前端寫法
- 獲取assetUrl的正確路徑
- 最后把這個變量賦給img的src屬性就可以了
九、dialog對話框
- 這里調用的是系統的對話框,有5種
- 需要在tauri.conf.json里配置api開放,教程里設置了全部開發
- 前端
- 選擇文件夾
以上的一些API,可能需要進入到tauri1里面去看
十、自定義窗口的配置
https://tauri.app/zh-cn/learn/window-customization/
- 上面的地址,可以在前端,通過css、html,模擬一個標題欄目
https://v1.tauri.app/v1/api/config#windowsconfig
- 這個地址可以配置tauri.config.json來設置窗口的大小
十一、系統托盤
- 通過配置,配置系統托盤
https://tauri.app/zh-cn/learn/system-tray/
- 關于系統托盤的說明,制作托盤有Js前端定義,和Rust后端定義2種類型
- 看我們的功能是在后端比較多,還是前端比較多
十二、開屏界面
https://tauri.app/zh-cn/learn/splashscreen/
- 教程通過增加一個窗口,并把主窗口隱藏,在rust里寫了隱藏開屏窗口和打開主窗口的函數,通過前端,調用此函數來實現
- 窗口的html文件,放在public里面
- 窗口可以通過label來得到
十三、多窗口
- 可以通過前端,來新建,設置新窗口的各項屬性
- 也可以在tarui.conf.json里把窗口先定義好,通過前端顯示此窗口
- 教程提示,vue的路徑使用,可能需要加#好
十四、導出
- 運行npm run tauri build,過程中出現需要下載的文件
- 教程里會讓放在C:/用戶…/AppData 下面
- 另外一種方式是通過注冊表
配置系統變量
TAURI_NSIS_DIR
D:\TauriSDK\NSIS配置系統變量
變量名:WIX
變量值:解壓目錄的路徑(例如:C:\wix)
同時,將解壓目錄中的bin文件夾添加到PATH環境變量中:
在系統變量中找到Path,點擊編輯。
添加一個新的條目:%WIX%\bin(或者直接寫絕對路徑,如C:\wix\bin)