一. 前言
在上一篇文章《使用Rust和WebAssembly整花活儿(一)——快速开始》中,描述了如何创建项目和快速生成wasm并在前端中使用,迈出了整花活儿的第一步。
在开发 Web 应用程序时,使用 Rust 编写的 Wasm 模块可以提供更高的性能和更好的安全性。但是,为了与现有的 JavaScript 代码集成,必须实现 Rust 与 JS 之间的交互。Rust 与 JS 交互的主要目的是将两种语言的优势结合起来,以实现更好的 Web 应用程序。
本篇文章中,将基于上一篇文章中创建的项目来继续开发。
源码:github.com/Kuari/hello-wasm
二. 环境
- Rust 1.70.0
- wasm-bindgen 0.2.87
- web-sys 0.3.64
三. DOM
1. 配置依赖
要操作DOM,需要引入新的依赖web-sys
,因此,可以配置Cargo.toml
中依赖如下:
[dependencies]
wasm-bindgen = "0.2.87"
web-sys = { version = "0.3.64", features = [] }
你或许会好奇,这个features
是什么,讲真,我一开始很好奇,又没看到什么特别的说明,试错才发现,原来是要手动引入功能依赖…比如说,当你需要在Rust中使用JS的console
,那么你需要在features
中加入console
。
2. 获取Document
在Rust中使用Document
,我们需要按照上一步的说明,添加features
。那么这里有一个依赖关系,首先在Rust中获取window
,然后再获取document
。
因此,添加features
后如下:
[dependencies]
wasm-bindgen = "0.2.87"
web-sys = { version = "0.3.64", features = ["Window", "Document"] }
然后在lib.rs
中创建一个函数,用来调用document
:
#[wasm_bindgen]
pub fn update_message() {
let window = web_sys::window().expect("Failed to load window");
let document = window.document().expect("Failed to load document");
}
那么,现在就是在Rust中解锁了document
,就可以在前端为所欲为了!
3. 操作Element
那么开始操作一波,首先得获取到Element
…
是的,你没有想错,继续来添加features
吧,此处要添加一个Element
:
[dependencies]
wasm-bindgen = "0.2.87"
web-sys = { version = "0.3.64", features = ["Window", "Document", "Element"] }
ok,那么继续。此处设定函数传入两个参数selector
和message
,然后通过selector
获取element,更新值为message
参数的值。完整函数如下:
#[wasm_bindgen]
pub fn update_message(selector: &str, message: &str) {
let window = web_sys::window().expect("Failed to load window");
let document = window.document().expect("Failed to load document");
let element = document.query_selector(selector).expect("Failed to load element");
if let Some(element) = element {
element.set_inner_html(message);
} else {
panic!("Failed to set inner html")
}
}
4. 编译
将写完的Rust项目编译成wasm:
wasm-pack build --target web
5. 在html中调用
基于上一篇文章的项目中的html,此处添加一个div
,id为message
,添加调用wasm的update_message
函数,代码如下:
<body>
<div id="message"></div>
</body>
<script type="module">
import init, {
update_message } from './pkg/hello_wasm.js'; // 引入update_message函数
const run = async () => {
await init();
update_message('#message', '<h1>Hello, Rust!</h1>'); // 调用update_message函数
}
run();
</script>
6. 在浏览器验证
启动一个http server,然后在浏览器查看,可以看到在页面上出现一个h1
标签的Hello, Rust!
。
7. 发现更多方法
按照文章来写的过程中,你应该会发现一个问题——怎么这些方法没有补全?!
是的,没错的,(至少我发现)当前web-sys
并没有补全,所以只能结合开发者优秀的前端技能和丰富的官方文档来开发了。
四. Rust与JS的类型相互转换
对于wasm而言,性能固然是提升的,但是类型转换一直是个问题。当