使用 RSX 构建用户界面

使用RSX构建用户界面

Dioxus会将内容渲染为HTML格式。若您不熟悉HTML,本指南将帮助您掌握基础知识。更多详细信息可参考MDN文档。

文本节点

任何用引号包围的内容在rsx中都会渲染为文本节点:

rust 复制代码
rsx! {
    "Hello world"
}

您可以在文本中包含格式化片段,就像使用 format! 宏一样:

rust 复制代码
let user = use_signal(|| User {
    name: "Dioxus".to_string(),
});
rsx! {
    // Unlike the format macro, you can include many expressions inline in the formatted text
    "Hello {user.read().name}"
}

元素

HTML最基本的构建单元是元素。在rsx中,你可以通过名称后跟大括号来创建元素。最常见的元素之一是input元素。input元素创建一个交互式输入框:

rust 复制代码
rsx! {
    input {}
}

额外说明:Web组件名称中包含连字符的元素即为Web组件。Web组件在dioxus中直接渲染且不进行类型检查。我们建议将Web组件封装在类型安全的组件中,以提升使用便捷性。

rust 复制代码
rsx! {
    my-web-component {}
}

属性

属性为元素提供额外信息。在元素大括号内,通过 input属性名称、冒号及值(通常为格式化字符串)即可在dioxus中指定属性。我们可利用属性设置输入元素的类型 type。默认类型为文本(显示文本输入框),但可将其设为number 类型以仅接受数字输入:

rust 复制代码
rsx! {
    input { type: "number" }
}

与文本节点类似,属性也可以包含格式化片段。我们可以将input元素的值设置为信号来控制它:

rust 复制代码
let mut value = use_signal(|| "Hello world".to_string());
rsx! {
    input { value: "{value}" }
}

条件属性

您可以通过将属性值设置为未终止的if语句来条件性地设置属性。如果if语句评估为真,则该属性将被设置:

rust 复制代码
let number_type = use_signal(|| false);
rsx! {
    input { type: if number_type() { "number" } }
}

事件监听器

事件监听器可用于响应用户输入。在rsx中,事件处理程序始终以on开头。其语法与常规属性相同,但事件处理程序仅接受响应事件的闭包 。我们可以为input元素的oninput事件附加事件监听器,以监听输入内容的变化:

rust 复制代码
let mut value = use_signal(|| "Hello world".to_string());
rsx! {
    input {
        oninput: move |event| value.set(event.value()),
        value: "{value}"
    }
}

子元素

在添加所有属性和事件监听器之后,您可以在元素中添加子元素。元素可以接受文本、组件或其他元素作为子元素。我们可以在输入框周围添加一个div元素来居中显示:

rust 复制代码
rsx! {
    div {
        // display sets the layout mode of the element
        display: "flex",
        // justify-content centers the element horizontally
        justify_content: "center",
        input {
            type: "number"
        }
    }
}

循环

您可以在 rsx 中直接插入 for 循环。循环体可接受任意数量的子元素,这些子元素将在每次循环迭代时渲染。HTML 中的 ul 元素会渲染一个无序列表,其中包含任意数量的 li(列表项)元素。我们可以利用这两个元素在循环中渲染项目列表:

rust 复制代码
let mut items = use_signal(|| vec!["Hello", "Dioxus"]);

rsx! {
    ul {
        for item in items.iter() {
            li { "{item}" }
        }
    }
}

列表中的每个项都应具有在多次重渲染过程中保持稳定的唯一值,称为 。键用于在比较差异时识别项的移动方式。若无键,在列表中重新排序项时,很容易意外丢失或移动状态。我们可通过使用 key 属性为列表项添加键:

rust 复制代码
let mut items = use_signal(|| vec!["Hello", "Dioxus"]);

rsx! {
    ul {
        for item in items.iter() {
            li { key: "{item}", "{item}" }
        }
    }
}

if 语句

rsx 中也可使用 if/else 语句。if 语句的每个分支都接受子节点,当条件为真时这些子节点将被渲染。我们可以使用 if 语句来条件性地渲染登录界面:

rust 复制代码
let logged_in = use_signal(|| false);

rsx! {
    div {
        if logged_in() {
            "You are logged in"
        } else {
            "You are not logged in"
        }
    }
}

为何选择RSX而非HTML?

若您见过ReactJSX或Rust语言的html!{}宏,或许会好奇Dioxus为何选择自定义语法而非更接近HTML的语法。

原因如下:

  • RSX无需额外工具即可实现代码高亮和代码折叠
  • RSX输入更快捷------大括号自动闭合
  • RSX并非全是HTML------Dioxus可在非HTML场景中使用
  • HTML不符合Rust语法规范------并非所有HTML元素都能在html!{}中使用
相关推荐
前端小万1 天前
一个全栈流程图应用
全栈
像风一样自由20201 天前
Python与Rust语法对比详解:从入门到精通
开发语言·python·rust
xiezhr1 天前
一个真·免费、真·开源的远程桌面神器——RustDesk
运维·rust·远程办公·远程
受之以蒙2 天前
Rust & WebAssembly 实践:构建一个简单实时的 Markdown 编辑器
笔记·rust·webassembly
我在书社写代码2 天前
Vue 3 + TypeScript + Vite 服务端渲染项目
全栈
Source.Liu2 天前
【Rust】 2. 数据类型笔记
开发语言·笔记·rust
lpfasd1233 天前
鸿蒙OS与Rust整合开发流程
华为·rust·harmonyos
m0_480502644 天前
Rust 登堂 之 类型转换(三)
开发语言·后端·rust