Rust如何使用Sauron實(shí)現(xiàn)Web界面交互
簡(jiǎn)介
Sauron 是一個(gè)多功能的 Web 框架和庫(kù),用于構(gòu)建客戶(hù)端和/或服務(wù)器端 Web 應(yīng)用程序,重點(diǎn)關(guān)注人體工程學(xué)、簡(jiǎn)單性和優(yōu)雅性。這使您可以編寫(xiě)盡可能少的代碼,并更多地關(guān)注業(yè)務(wù)邏輯而不是框架的內(nèi)部細(xì)節(jié)。
github:https://github.com/ivanceras/sauron
文檔:https://sauron-rs.github.io/
架構(gòu)
Sauron 遵循模型-視圖-更新架構(gòu)(也稱(chēng)為 Elm 架構(gòu)),它總是分為三個(gè)部分:
- 模型 - 應(yīng)用程序的狀態(tài)
- 視圖 - 一種將狀態(tài)轉(zhuǎn)換為 HTML 的方法
- 更新 - 一種根據(jù)消息更新?tīng)顟B(tài)的方法
Application 和組件
為了使模型在 Sauron 程序中運(yùn)行,它必須實(shí)現(xiàn) Application trait,然后定義下面兩個(gè)函數(shù):
- view 函數(shù):該函數(shù)告訴程序如何顯示模型。
- update 函數(shù):該函數(shù)描述如何根據(jù)消息更新模型狀態(tài)。
簡(jiǎn)單入門(mén)示例
先決條件
確保已安裝所有必備組件:
- rust and cargo:Rust基礎(chǔ)環(huán)境和工具。
- wasm-pack:將 rust 代碼編譯到 webassembly 中,然后放入 ./pkg 目錄中。
- basic-http-server:在本地提供靜態(tài)文件。
執(zhí)行以下命令安裝wasm-pack:
cargo install wasm-pack
執(zhí)行以下命令安裝basic-http-server:
cargo install basic-http-server
wasm-pack 默認(rèn)會(huì)使用 wasm-opt 工具進(jìn)行大小優(yōu)化,而這個(gè)工具也是運(yùn)行時(shí)下載安裝的。下載 wasm-opt 使用的是 github 鏈接,國(guó)內(nèi)環(huán)境大概率是下載失敗的,可以參考 如何安裝WASM-OPT? 手動(dòng)下載 wasm-opt.exe 后放到 .cargo\bin路徑下。
創(chuàng)建項(xiàng)目
創(chuàng)建一個(gè)名為 hello 的新項(xiàng)目:
cargo new --lib hello
在 Cargo.toml 中指定這個(gè) crate 需要編譯為 cdylib(動(dòng)態(tài)系統(tǒng)庫(kù)):
[lib] crate-type = ["cdylib"]
執(zhí)行以下命令,添加sauron作為項(xiàng)目的依賴(lài)項(xiàng)。
cargo add sauron
編譯庫(kù)文件
修改 src/lib.rs代碼,在段落中顯示“hello”文本:
use sauron::{node, wasm_bindgen, Application, Cmd, Node, Program}; struct App; impl Application<()> for App { fn view(&self) -> Node<()> { node! { <p> "hello" </p> } } fn update(&mut self, _msg: ()) -> Cmd<Self, ()> { Cmd::none() } } //函數(shù)應(yīng)該在加載 wasm 模塊時(shí)自動(dòng)啟動(dòng),類(lèi)似于 main 函數(shù) #[wasm_bindgen(start)] pub fn main() { Program::mount_to_body(App::new()); }
- view 方法中使用 node! 宏,采用類(lèi)似 html 的語(yǔ)法來(lái)顯示應(yīng)用程序。
- 為 App 實(shí)現(xiàn) Application 特征,實(shí)現(xiàn)必要的方法來(lái)告訴 sauron 應(yīng)用程序的行為。
- 這里的 main 函數(shù)在加載 wasm 模塊時(shí)自動(dòng)啟動(dòng),函數(shù)可以任意命名,只要配置 start 即可。
執(zhí)行以下命令進(jìn)行編譯:
wasm-pack build --release --target=web
編譯時(shí)間稍微有點(diǎn)長(zhǎng),wasm-pack 會(huì)在項(xiàng)目中創(chuàng)建一個(gè)文件夾 ./pkg,里面包含生成的編譯文件,只需要關(guān)注其中 2 個(gè)文件:
hello.js hello_bg.wasm
它們的名稱(chēng)派生自給定的包名稱(chēng) <package_name>.js 和 <package_name>_bg.wasm。
引用庫(kù)文件
在項(xiàng)目的根目錄中創(chuàng)建 index.html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> </head> <body> <script type=module> import init from './pkg/hello.js'; await init().catch(console.error); </script> </body> </html>
- 使用的是 <script type=module>, 從 ./pkg 文件夾中引用了 ./pkg/hello.js 。
- 在后臺(tái),./pkg/hello.js 將負(fù)責(zé)在后臺(tái)加載 ./pkg/hello_bg.wasm。
運(yùn)行項(xiàng)目
重新編譯webapp,每次對(duì) rust 代碼進(jìn)行更改時(shí)發(fā)出此命令。
wasm-pack build --release --target=web
最后使用 basic-http-server 提供文件:
basic-http-server
默認(rèn)情況下,它在端口 4000 中提供頁(yè)面,導(dǎo)航到 http://127.0.0.1:4000 以查看“hello”消息。
界面交互示例
在瀏覽器中顯示 3 個(gè)按鈕,單擊這些按鈕可以增加/減少和重置計(jì)數(shù)。
創(chuàng)建項(xiàng)目
創(chuàng)建一個(gè)名為 counter 的新 rust 庫(kù)項(xiàng)目:
cargo new --lib counter
接下來(lái)修改 crate 類(lèi)型為 “cdylib” 庫(kù) ,添加 sauron 依賴(lài),這里不在贅述。
編譯庫(kù)文件
在 src/lib.rs 中放入此代碼:
use sauron::prelude::*; use sauron::node; struct App { count: i32, } //添加了一個(gè)函數(shù) new 來(lái)創(chuàng)建以 count 0 開(kāi)頭的初始狀態(tài) App impl App { fn new() -> Self { App { count: 0 } } }
定義應(yīng)用程序?qū)⒕哂械囊唤M操作:
enum Msg { Increment, Decrement, Reset, }
為模型 App 實(shí)現(xiàn) Application 特征:
impl Application<Msg> for App { fn view(&self) -> Node<Msg> { node! { <main> <input type="button" value="+" on_click=|_| { Msg::Increment } /> <button class="count" on_click=|_|{Msg::Reset} >{text(self.count)}</button> <input type="button" value="-" on_click=|_| { Msg::Decrement } /> </main> } } fn update(&mut self, msg: Msg) -> Cmd<Self, Msg> { match msg { Msg::Increment => self.count += 1, Msg::Decrement => self.count -= 1, Msg::Reset => self.count = 0, } Cmd::none() } }
- view 方法返回類(lèi)型為 Node<Msg>,這意味著它創(chuàng)建一個(gè) html 節(jié)點(diǎn),其中它的任何成員 html 元素都有一個(gè)事件偵聽(tīng)器,該事件偵聽(tīng)器可以向程序處理程序發(fā)出 Msg 消息。
- update 方法接受 Msg 作為參數(shù),并根據(jù) Msg 的變體修改模型 App。
實(shí)現(xiàn)應(yīng)用函數(shù)
接下來(lái)為 wasm Web 應(yīng)用定義入口點(diǎn),通過(guò)使用 #[wasm_bindgen(start)] 注釋公共函數(shù)來(lái)完成:
#[wasm_bindgen(start)] pub fn start() { Program::mount_to_body(App::new()); }
為了演示純函數(shù)交互,這里再添加一個(gè)簡(jiǎn)單的加法函數(shù):
#[wasm_bindgen] pub fn add(a: i32, b: i32) -> i32 { a + b }
如果只需要js調(diào)用Rust的函數(shù),那只需要添加 wasm_bindgen 依賴(lài)即可,參考 使用Rust和WebAssembly整花活兒(一)——快速開(kāi)始。
引用庫(kù)文件
在項(xiàng)目基本文件夾的 index.html 文件中鏈接應(yīng)用,可以像往常一樣放置樣式:
<html> <head> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"/> <title>Counter</title> <style type="text/css"> body { font-family: verdana, arial, monospace; } main { width:30px; height: 100px; margin:auto; text-align: center; } input, .count{ font-size: 40px; padding: 30px; margin: 30px; } </style> <script type=module> import init, { add } from './pkg/counter.js'; await init().catch(console.error); const result = add(1, 2); console.log(`the result from rust is: ${result}`); </script> </head> <body> </body> </html>
注意上面的 import init, { add } from ,add 函數(shù)在使用前需要導(dǎo)入,否則會(huì)調(diào)用失敗。
運(yùn)行項(xiàng)目
編譯庫(kù)文件:
wasm-pack build --release --target=web
啟動(dòng)靜態(tài)站點(diǎn):
basic-http-server
訪問(wèn) http://127.0.0.1:4000 查看效果:
參考資料
- 如何安裝WASM-OPT?
- 國(guó)內(nèi)網(wǎng)絡(luò)環(huán)境下配置 wasm 開(kāi)發(fā)環(huán)境
- 使用Rust和WebAssembly整花活兒(一)——快速開(kāi)始
到此這篇關(guān)于Rust使用Sauron實(shí)現(xiàn)Web界面交互的文章就介紹到這了,更多相關(guān)Rust Web界面交互內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust 利用 chrono 庫(kù)實(shí)現(xiàn)日期和字符串互相轉(zhuǎn)換的示例
在Rust中,chrono庫(kù)提供了強(qiáng)大的日期和時(shí)間處理功能,使得日期與字符串之間的轉(zhuǎn)換變得簡(jiǎn)單,本文介紹了如何在Rust中使用chrono庫(kù)將日期轉(zhuǎn)換成字符串,以及如何將字符串解析為日期,對(duì)于需要進(jìn)行日期時(shí)間格式化、解析或進(jìn)行時(shí)區(qū)處理的開(kāi)發(fā)者來(lái)說(shuō),chrono庫(kù)是一個(gè)不可或缺的工具2024-11-11Rust在寫(xiě)庫(kù)時(shí)實(shí)現(xiàn)緩存的操作方法
Moka是一個(gè)用于Rust的高性能緩存庫(kù),它提供了多種類(lèi)型的緩存數(shù)據(jù)結(jié)構(gòu),包括哈希表、LRU(最近最少使用)緩存和?支持TTL(生存時(shí)間)緩存,這篇文章給大家介紹Rust在寫(xiě)庫(kù)時(shí)實(shí)現(xiàn)緩存的相關(guān)知識(shí),感興趣的朋友一起看看吧2024-01-01Rust Atomics and Locks并發(fā)基礎(chǔ)理解
這篇文章主要為大家介紹了Rust Atomics and Locks并發(fā)基礎(chǔ)理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02通過(guò)rust實(shí)現(xiàn)自己的web登錄圖片驗(yàn)證碼功能
本文介紹了如何使用Rust和imagecrate庫(kù)生成圖像驗(yàn)證碼,首先,通過(guò)Cargo.toml文件添加image依賴(lài),然后,生成純色圖片并編輯驗(yàn)證圖片,接著,編寫(xiě)隨機(jī)函數(shù)獲取字符,并通過(guò)循環(huán)生成驗(yàn)證碼圖片,最終,通過(guò)運(yùn)行函數(shù)驗(yàn)證驗(yàn)證碼圖片是否生成,感興趣的朋友一起看看吧2025-03-03在Rust中編寫(xiě)自定義Error的詳細(xì)代碼
Result<T, E> 類(lèi)型可以方便地用于錯(cuò)誤傳導(dǎo),Result<T, E>是模板類(lèi)型,實(shí)例化后可以是各種類(lèi)型,但 Rust 要求傳導(dǎo)的 Result 中的 E 是相同類(lèi)型的,所以我們需要編寫(xiě)自己的 Error 類(lèi)型,本文給大家介紹了在Rust中編寫(xiě)自定義Error的詳細(xì)代碼,需要的朋友可以參考下2024-01-01