這一節(jié),如果你是一個有web開發(fā)經(jīng)驗的同學,就非常好理解了,以為Tauri幾乎與web開發(fā)模式一模一樣,稍微有一些不同的只是他們的數(shù)據(jù)交互和資源調(diào)度有一些不同。 下面來我們通過一個簡單的例子,來說明Tauri的開發(fā)模式: 前后臺典型開發(fā)模式先來看一個典型的web開發(fā)模式: 先不管前臺UI的部分(因為我也不懂,所以我只能跳過),一般來說就是四個主體部分: 1. 前臺提交事件前臺一般會把需求提交給后臺,例如要獲取指定條件的數(shù)據(jù),前臺會獲取空間的值,例如某個時間范圍,然后把這個值通過一個from表單和submit事件提交給后臺指定的一個url接口,然后等待后臺接口響應。 2. 后端路由。這個部分負責前端調(diào)用或者說后臺提供給前端的URL與后臺實現(xiàn)功能的接口的映射。例如我在后臺寫了一個鑒權(quán)的接口: async fn authentication(username:&str, password:&str)->bool{ //代碼略 }
那么web前端是無法直接通過這個函數(shù)名來調(diào)用這個接口的,還需要發(fā)布做一個URL與這個接口對應起來,例如在actix-web框架里面,可以通過HttpServer里面的services,把/login這個URL與authentication這方法綁定起來。 HttpServer::new(|| { App::new() .wrap(middleware::Logger::default()) .service(web::resource("/login").to(authentication)) }).bind(("0.0.0.0", 8080))?.run() .await
這一步通常就叫做路由綁定。綁定之后,前端就可以通過http://ip:port/login 這個url來訪問這個接口的功能了。 3. 邏輯功能這部分沒啥說的,就是后臺寫的各種功能邏輯接口,例如需求參數(shù)解析、算法實現(xiàn)、數(shù)據(jù)處理、分析計算統(tǒng)計、數(shù)據(jù)庫CRUD啥的,是后臺碼農(nóng)的基本操作,這里就直接略過了。 4. 數(shù)據(jù)庫操作這部分狹義上可以看成了后臺的基本功能,也是后臺的代名詞,所以后臺碼農(nóng)通常被人稱為“Curd Boy”的來由。當然,廣義上來說,應該是數(shù)據(jù)源操作,因為后臺的數(shù)據(jù)可能來自redis這種緩存服務器,也可能來自Elasticsearch、HDFS、HBase這種非結(jié)構(gòu)化數(shù)據(jù)庫,甚至可能直接來自NAS、本地磁盤、對象云存儲等設備上的各種奇形怪狀的文件(比如GIS的可能就直接是讀取shapefile或者gdb、geopackage、tiff、三維體元、netcdf等)。 讀取完這些數(shù)據(jù)之后,大部分情況下不能通過二進制推送給前端,一般都會進行一個數(shù)據(jù)結(jié)構(gòu)的build,例如Restful接口都建議編譯成JSON,而圖形、視頻等非結(jié)構(gòu)化的數(shù)據(jù),就轉(zhuǎn)換為流提供給前端。 所以我們在開發(fā)的時候,也都通常是分成這四個部分就行開發(fā),除了全棧碼農(nóng),一般的開發(fā)小組都是分成前臺和后臺兩部分,前端負責UI和用戶交互部分,后端負責功能實現(xiàn),前后端之間僅進行數(shù)據(jù)的交互。 在Tauri里面,也基本上遵循了這個開發(fā)模式,下面來我們來簡單開發(fā)一個用戶登錄的頁面全流程。 Tauri開發(fā)示例1. 前端頁面的開發(fā):我這里寫了一個登錄用的頁面: (UI白板什么的,就不要在意了) <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="stylesheet" href="styles.css" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Tauri App</title> <script type="module" src="/main.js" defer></script> </head>
<body> <div class="container"> <h1>Tauri 登陸測試</h1> <form id="vaild-form"> <p>用戶名:<input id="vaild-username" placeholder="輸入用戶名..." /></p> <p>密碼:<input id="vaild-pwd" type="password" placeholder="輸入密碼..." /></p> <p><button type="submit">登錄</button></p> </form>
<p id="vaild-msg"></p> </div> </body> </html>
2. 后臺路由和邏輯功能的實現(xiàn):#[tauri::command] fn vaild(name: &str,pwd: &str) -> bool{ match name { "admin" =>{ if pwd == "123"{ true } else{ false } } _=>{ if name == pwd { true } else{ false } } } }
代碼的邏輯很簡單,如果用戶名是admin,則判斷密碼是不是等于123,如果用戶不是admin,則對比用戶名密碼是不是一樣的;通過就返回一個布爾類型的true,驗證失敗則返回一個布爾類型的false。(當然,正常代碼應該是要通過數(shù)據(jù)庫去獲取驗證用戶名密碼的,且密碼是要加密的,這里作為測試,我就不搞這么麻煩了,反正邏輯是一樣的)。 方法最上面的#[tauri::command] 是Rust語法中的一個屬性宏(attribute macro),它用于標記一個函數(shù),使其可以在 Tauri 框架中作為命令(command)使用。 3. 注冊路由#[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_shell::init()) .invoke_handler(tauri::generate_handler![vaild]) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
可以看見,代碼中.invoke_handler(tauri::generate_handler![vaild]) 這一句,就是把我們的vaild 函數(shù)注冊成了一個可以在前端調(diào)用的方法。 4. 前端事件調(diào)用:注冊一個時間,如果觸發(fā)了前端的submit,則執(zhí)行下面的方法: window.addEventListener("DOMContentLoaded", () => { username = document.querySelector("#vaild-username"); pwd = document.querySelector("#vaild-pwd"); vaildMsgEl = document.querySelector("#vaild-msg"); document.querySelector("#vaild-form").addEventListener("submit", (e) => { e.preventDefault(); vaild(); }); });
調(diào)用Rust接口的功能函數(shù)編寫: 直接用過invoke去調(diào)用我們后臺編寫的vaild方法,傳遞username和pwd兩個參數(shù),然后通過true/false來判斷登錄是否成功,并且在進行提示: async function vaild(){ let res = await invoke("vaild", { name: username.value ,pwd: pwd.value }); if (res){ vaildMsgEl.innerHTML = '<font color="green">登錄成功</font>'; } else{ vaildMsgEl.innerHTML = "<font color='red'>登錄失敗</font>"; } }
然后運行,測試結(jié)果如下:輸入abc/1234,用戶名密碼不一致,顯示登錄失敗 輸入abc/abc,用戶密碼一致,登錄成功 輸入admin/123,指定管理員登錄成功 打完收工。
|