序言
依旧使用例子演示,例子包含定义组件,以及将组件点击事件传递给上一个组件处理,例子如下:
src/btn_widget.rs
use yew::prelude::*;
pub struct MyButton {
link: ComponentLink<Self>,
props: Props,
}
#[derive(PartialEq, Properties, Clone)]
pub struct Props {
pub txt: String,
pub callback: Callback<()>,
}
pub enum Msg {
Click,
}
impl Component for MyButton {
type Message = Msg;
type Properties = Props;
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
Self { link, props }
}
fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg {
Msg::Click => {
self.props.callback.emit(());
}
}
true
}
fn change(&mut self, props: Self::Properties) -> ShouldRender {
// 组件必须包含下面代码
self.props = props;
true
}
fn view(&self) -> Html {
html! {
<button class={"button"} onclick=self.link.callback(|_| Msg::Click)>{ self.props.txt.clone() }</button>
}
}
}
src/main.rs
use yew::prelude::*;
mod btn_widget;
use btn_widget::MyButton;
enum Msg {
AddOne,
AddTwo,
}
struct Model {
link: ComponentLink<Self>,
item_type: i32,
}
impl Model {
fn btn_click(&mut self) {
// js_api::js_alert("hello from wasm!");
self.item_type = 1;
}
fn btn_two_click(&mut self) {
self.item_type = 0;
}
fn hello_world_ui(&self) -> Html {
html! {
<div>
<center>
<h1>{"布局以被切换"}</h1>
<button class={"button"} onclick=self.link.callback(|_| Msg::AddTwo)>{ "点击 上一个布局" }</button>
</center>
</div>
}
}
fn def_ui(&self) -> Html {
html! {
<div>
<center>
<p>{ "yew 测试实例一" }</p>
<MyButton txt={String::from("点击 下一个布局")} callback=self.link.callback(|_| Msg::AddOne) />
// <button class={"button"} οnclick=self.link.callback(|_| Msg::AddOne)>{ "点击 下一个布局" }</button>
// <button class={"button"} οnclick=self.link.callback(|_| Msg::AddOne)>{ "点击 下一个布局" }</button>
</center>
</div>
}
}
}
impl Component for Model {
type Message = Msg;
type Properties = ();
fn create(_props: Self::Properties, link: ComponentLink<Self>) -> Self {
Self { link, item_type: 0 }
}
fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg {
Msg::AddOne => {
self.btn_click();
true
}
Msg::AddTwo => {
self.btn_two_click();
true
}
}
}
fn change(&mut self, _props: Self::Properties) -> ShouldRender {
false
}
fn view(&self) -> Html {
match self.item_type {
0 => self.def_ui(),
_ => self.hello_world_ui(),
}
}
}
fn main() {
yew::start_app::<Model>();
}
总结
比较难的点在于点击事件如何传递,毕竟rust和其它语言不同,之前使用过Box等智能指针,但是发现只有Rc符合使用场景,由于官方文档并没有关于Callback的介绍,最终在某个demo中找到对应的解决方式,和我构想类似,这个例子比较简单,主要演示yew和react的思想与使用接近一致(别人说的),当然yew的组件化思想比较好,当然缺点还是有的比如写html代码没有提示;Msg主要作用是定义事件的响应,Props 用于数据传递或者说是需要外部传递的数据,没有可以不写,yew组件必须实现Component这个接口,每一个函数都是对应生命周期具体的就不展开了。