之前写的记事本应用,基本没有关注UI之类的,最近开始进一步学习Yew这个框架的一些东西。之前使用Vue的时候,那会使用Element UI这个组件库,简单的看了下源码,准备仿照着写一个按钮的组件,也算是对Yew的组件化的研究。
样式这块其实要比较重要,不然太丑了,直接使用Element UI的样式。
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
给我们的按钮起名为YewButton,相关参数主要参考Element UI按钮组件。yew_button.rs代码:
use yew::prelude::*;
pub enum Msg {}
pub struct YewButton {}
#[derive(Clone, PartialEq, Properties)]
pub struct YewButtonProps {
#[prop_or_default]
pub disabled: bool,
#[prop_or_default]
pub style: String,
pub title: AttrValue,
pub on_clicked: Callback<MouseEvent>,
#[prop_or_default]
pub loading:bool
}
impl Component for YewButton {
type Message = Msg;
type Properties = YewButtonProps;
fn create(_ctx: &Context<Self>) -> Self {
Self {}
}
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {}
}
fn view(&self, ctx: &Context<Self>) -> Html {
let title = ctx.props().title.clone();
let disabled = ctx.props().disabled.clone();
let style = ctx.props().style.clone();
let loading = ctx.props().loading.clone();
let onclick = ctx.props().on_clicked.reform(move |event: MouseEvent| {
event.stop_propagation();
event.clone()
});
let mut classes = Vec::new();
classes.push(String::from("el-button"));
if !style.is_empty() {
let ss = format!("el-button--{}", style);
classes.push(ss);
}
if disabled {
classes.push(String::from("is-disabled"));
}
html! {
<button class={classes!(classes.clone())} {onclick} disabled={disabled.clone()} >
{title.clone()}
if loading {
<i class="el-icon-loading"></i>
}
</button>
}
}
}
下面是如何使用,components_test.rs代码
use gloo_console::log;
use yew::prelude::*;
use super::yew_button::YewButton;
pub enum Msg {
BtnClick
}
pub struct ComponentsTest {
}
impl Component for ComponentsTest {
type Message = Msg;
type Properties = ();
fn create(_ctx: &Context<Self>) -> Self {
Self {
}
}
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::BtnClick=>{
log!("按钮点击");
false
}
}
}
fn view(&self, ctx: &Context<Self>) -> Html {
let on_clicked = ctx.link().callback(move|_e:MouseEvent|{
Msg::BtnClick
});
html! {
<div class="center-container">
<h1>{ "组件测试" }</h1>
<YewButton style="primary" title="按钮测试" on_clicked={on_clicked.clone()} />
<br/>
<YewButton style="primary" title="按钮测试" loading={true} on_clicked={on_clicked.clone()} />
</div>
}
}
}
整个下来感觉还算顺利,写Rust得时刻面对编译不过的问题,感觉还是有不少的坑,相比JS,用Rust写前端目前来看还是有点卡。其实CSS和HTML这些没有变,只是把JS换成了Rust, 浏览器相关的API也没有变,只是换一种写法了。对于Rust,因为运行环境变成了浏览器,所以有些东西也无法使用。虽然有不少语言可以编译成wasm,但是就目前来看Rust确实是最上心的一个。
为了学习Yew我单独创建了一个项目,以上完整的代码都在这个项目yew-lab里面。