rust yew使用教程(二)

序言

    依旧使用例子演示,例子包含定义组件,以及将组件点击事件传递给上一个组件处理,例子如下:

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这个接口,每一个函数都是对应生命周期具体的就不展开了。

上一篇:条件语句


下一篇:springboot异常处理