Dioxus 开发指南

特殊属性

在这一章节中,我们需要了解 Dioxus 的特殊类型:

  • dangerous_inner_html
  • boolean attributes
  • prevent_default
  • ..attributes
  • event handlers as string attributes
  • value checked and selected

原生HTML§

在 React 中,我们可以直接返回一段原生的 HTML/CSS/JS 代码到渲染器中, 而在 Dioxus 中我们使用 dangerous_inner_html 也能完成这一点。

比如说,我们希望被 Markdown 转换后的 post.html 能直接内嵌到 Dioxus 应用中。

fn BlogPost(cx: Scope) -> Element {
    let contents = include_str!("../post.html");
    cx.render(rsx!{
        div {
            class: "markdown",
            dangerous_inner_html: "{contents}",
        }
    })
}

上方代码就相当于直接把 HTML 代码写入到这个 div 中去了。

请一定要注意:dangerous_inner_html 的使用非常危险,因为它无法直接的防止注入攻击(XSS)所以说,请确保你传入的 HTML 是安全的。 否则直接使用所造成的问题是不可逆的,它非常危险!!

布尔属性§

大多数属性都是 K = V 的结构,但是 HTML 中也有一些特殊的属性,它们的值为 Boolean 类型。 比如说我们最常用的 hidden 属性,它会隐藏这个标签的显示。比如说这样的一个 Demo 代码:

rsx!{
    div {
        hidden: "false",
        "hello"
    }
}

它的 HTML 结果为:

<div>hello</div> 

最终并不会包含 hidden 属性,因为它的值为 false,除了 false 的所有值都为 true

以下是我们整理出的 Boolean 属性列表(只有它们支持 Boolean 设置):

  • allowfullscreen
  • allowpaymentrequest
  • async
  • autofocus
  • autoplay
  • checked
  • controls
  • default
  • defer
  • disabled
  • formnovalidate
  • hidden
  • ismap
  • itemscope
  • loop
  • multiple
  • muted
  • nomodule
  • novalidate
  • open
  • playsinline
  • readonly
  • required
  • reversed
  • selected
  • truespeed

对于任何其他属性,false 的值将被直接发送到 DOM。

拦截默认事件§

prevent_default 属性将会对默认的事件处理进行拦截,可用于拦截表单的提交之类的。

rsx!{
    input {
        oninput: move |_| {},
        prevent_default: "oninput",

        onclick: move |_| {},
        prevent_default: "onclick",
    }
}

传递属性到子元素§

就像 Dioxus 支持将 Props 拓展到组件中一样,我们也支持将 属性 扩展到组件中。 这允许你将任意属性通过 Props 传递到元素中。

#[derive(Props)]
pub struct InputProps<'a> {
    pub children: Element<'a>,
    pub attributes: Attribute<'a>
}

pub fn StateInput<'a>(cx: Scope<'a, InputProps<'a>>) -> Element {
    cx.render(rsx! (
        input {
            ..cx.props.attributes,
            &cx.props.children,
        }
    ))
}

请注意:这个特性将在 v0.1.8 版本实现。

控制表单的特殊属性§

在 Dioxus 我们如何实现所谓的 双向绑定 呢?

双向绑定指的不单单是页面会根据后端变量值实时更新前端数据,也可以在前端的编辑操作下更新后端变量值。 比如说当一个输入框更新了数据,则同时更新后端变量值:

let (value, set_value) = use_state(&cx, || String::from("hello world"));

rsx! {
    input {
        oninput: move |evt| set_value(evt.value.clone()),
        value: "{value}",
    }
}

在上方演示中,输入框便编辑后,回调函数会自动更新 value 的值。

// 这是一个更直观的演示代码
let (value, set_value) = use_state(&cx, || String::from("hello world"));

rsx! {
    input {
        oninput: move |evt| set_value(evt.value.clone()),
        value: "{value}",
    }
    p { "Input Value: {value}" }
}

在上方代码中,当输入框的内容被改变,P 标签内容也会随之改变。

Javascript 代码事件§

如果你希望在 onclick 等事件中运行 JS 代码,你可以直接传递一个 JS 代码字符串:

rsx!{
    div {
        // 使用 Rust 处理
        oninput: move |_| {},

        // 使用 Javascript 处理
        oninput: "alert('hello world')",
    }
}

当然,这里也有一个简单的封装库可以实现 JS 代码调用:YuKun-Liu/Golde 而这个库我们将在后面的第三方包内容中讲到。

到此,UI设计方向的内容我们算是讲解完毕了,接下来我们会进入组件封装的内容。