傳統(tǒng)的web開發(fā)中,前后臺(tái)數(shù)據(jù)交互,一般有兩種情況:- 系統(tǒng)通用的對(duì)象,例如字符串、數(shù)值、列表、布爾等類型,是需要進(jìn)行build和parse,不管是前端傳遞到后端的還是后端像前端傳輸?shù)膮?shù),都需要進(jìn)行構(gòu)建,然后進(jìn)行序列化和反序列化,但是只要涉及序列化和反序列化,可能就會(huì)帶來復(fù)雜對(duì)象解析的一些問題。
- 就是一些特殊的流式對(duì)象,例如前端要傳遞一個(gè)文件給后端(反之亦然),那需要把文件解析成二進(jìn)制流進(jìn)行傳輸,不過這一步通常是瀏覽器和中間件,利用HTTP的
RFC1867協(xié)議 通過enctype 的屬性定義multipart/form-data 來處理,不用你手動(dòng)寫代碼。
而我為什么要說Tauri是一個(gè)四不像的框架呢?因?yàn)檫@玩意兒作為一個(gè)桌面開發(fā),你說前后臺(tái)之間傳輸數(shù)據(jù)依然還需要走序列化和反序列這一套東西,如下所示: 我們先定義了一個(gè)結(jié)構(gòu),這個(gè)結(jié)構(gòu)里面還有一個(gè)枚舉,接下去我寫了一個(gè)方法,把他給返回給前臺(tái),這里我直接就靜態(tài)構(gòu)建了,當(dāng)然你從數(shù)據(jù)庫里面來構(gòu)造也行。 //血型,枚舉型類型 //無論是枚舉還是結(jié)構(gòu),都需要實(shí)現(xiàn)Serialize/ Deserialize,以進(jìn)行序列化和反序列,否則就會(huì)報(bào)錯(cuò)。 #[derive(Debug, Serialize, Deserialize)] enum Blood_Type{ A, B, O, AB, Rh }
#[derive(Debug, Serialize, Deserialize)] struct user_info{ username: String, nickname: String, email:String, age: u16, birthday: String, blood_type:Blood_Type, other:Vec<f32>,
} #[tauri::command] fn get_user_info(username:&str)-> user_info{ user_info{ username: username.to_owned(), nickname: "昵稱".to_owned(), email: "abcd@abde.com".to_owned(), age: 35, birthday: NaiveDate::from_ymd_opt(1999, 8, 16).unwrap().to_string(), blood_type: Blood_Type::A, other: vec![1.5,2.0,3.3,3.1,2.6] } }
<h1>Tauri 數(shù)據(jù)交互測(cè)試</h1> <form id="query-form"> <p>用戶名:<input id="query-username" placeholder="輸入用戶名..." /></p> <p><button type="submit">登錄</button></p> </form>
async function get_user_info(){ let res = await invoke("get_user_info", { username: username.value}); console.log(res); }
window.addEventListener("DOMContentLoaded", () => { username = document.querySelector("#query-username"); vaildMsgEl = document.querySelector("#query-msg"); document.querySelector("#query-form").addEventListener("submit", (e) => { e.preventDefault(); get_user_info(); }); });
運(yùn)行代碼,輸入用戶名,然后點(diǎn)擊F12查看前端控制臺(tái):很明顯的發(fā)現(xiàn),后端傳輸過來的代碼,都直接build成了json對(duì)象,在前端你直接用json的方法來機(jī)型解析使用即可。 ——所有,你就說,和Web開發(fā)有啥區(qū)別吧…… 同樣的,如果要從前端像后端傳輸對(duì)象,也是一樣,所不同的是前端的JS是一個(gè)弱類型的語言,可以直接定義JSON傳遞過去,而后端需要先有一個(gè)結(jié)構(gòu)才能對(duì)接起來,如下所示: //用JS定義了一個(gè)對(duì)象,這個(gè)對(duì)象的結(jié)構(gòu)與Rust里面的結(jié)構(gòu)一模一樣 //js 沒有枚舉型,就用對(duì)象一并模擬了, //這里注意,Rust的枚舉型默認(rèn)序列化之后是字符串類型的,所以這Js的也得模擬成字符串的值。 async function set_user_info(){ const Blood_Type = { A:"A", B:"B", O:"O", AB:"AB", Rh:"Rh" } const user_info = { username: "godxia", nickname: "蝦神", email:"godxia@abcd.com", age: 36, birthday: "1988-01-01", blood_type:Blood_Type.A, other:[1.1,2.2,3,3], }
await invoke("set_user_info", { user: user_info}); }
然后同樣在Rust里面接一下,并且打印出來: #[tauri::command] fn set_user_info(user:user_info)-> bool{ println!("{:?}",user); true }
執(zhí)行之后,結(jié)果如下: 可以看見,對(duì)象被序列化并且完整傳遞過來了。 我們可以繼續(xù)討論一下后端Rust開發(fā)的內(nèi)容,前端我是一個(gè)字母都寫不動(dòng)了……
|