3 个版本
0.1.2 | 2023 年 11 月 5 日 |
---|---|
0.1.1 | 2023 年 7 月 2 日 |
0.1.0 | 2023 年 7 月 2 日 |
#992 在 WebAssembly
650KB
320 行
Dioxus 的可排序组件
创建任何类型的可排序表格(和其他组件)的 Dioxus。
有关 英国首相 的完整示例(及相关代码)可供查看。完整文档和示例可在 https://docs.rs/dioxus-sortable 上找到
lib.rs
:
Dioxus 的可排序组件
创建任何类型的可排序表格(和其他组件)的 Dioxus。
重点是表格,但此库可以用于创建任何类型的可排序组件。您可以自定义表格。排序状态与数据分开保存。
在本文档中,您将看到类型 T
用于引用您要排序的数据类型。您还会看到 F
,它应该是一个枚举,用于引用 T
的每个可排序字段。您的 F
枚举应实现 PartialOrdBy
以进行排序,以及 Sortable
以描述如何排序。
我们使用 PartialOrd
允许具有 NULL 语义的类型进行排序。这在有 f64::NAN
或“未知”字段时很有用。它允许我们处理更通用的案例。我们尽量保持排序语义与 SQL 的 ORDER BY 子句相同。
用法
- 创建一个您希望排序的
struct T
。表格行。 - 创建一个描述
T
中每个可排序字段的enum F
。 - 为
F
实现PartialOrdBy
。这用于按F
排序T
。 - 为
F
实现Sortable
。这用于描述如何对F
进行排序。 - 在您的组件中调用 [
use_sorter()
] 并获取UseSorter
。 - 调用
UseSorter::sort
来排序数据。这可以在等待数据到达时条件性地调用。 - 使用 [
Th
] 创建一个表格,或者使用ThStatus
和UseSorter::toggle_field
编写自己的表格。
示例
查看 英国首相 的完整示例(代码)。您可以使用 dioxus serve --example prime_ministers
在本地修改并运行它。
下面是一个最小的示例,展示了如何使用这个库。
use dioxus::prelude::*;
use dioxus_sortable::{use_sorter, PartialOrdBy, SortBy, Sortable, Th};
/// Our table row. Type `T`.
#[derive(Clone, Debug, PartialEq)]
struct Person {
name: String,
age: u8,
}
/// Our table columns. Type `F`. One for each field in Person.
#[derive(Copy, Clone, Debug, Default, PartialEq)]
enum PersonField {
Name,
/// Use default for the initial sort.
#[default]
Age,
}
/// Specify how we sort our `Person` using `PersonField`.
impl PartialOrdBy<Person> for PersonField {
fn partial_cmp_by(&self, a: &Person, b: &Person) -> Option<std::cmp::Ordering> {
// Note how it's just a passthru to `PartialOrd` for each field.
match self {
PersonField::Name => a.name.partial_cmp(&b.name),
PersonField::Age => a.age.partial_cmp(&b.age),
}
}
}
/// Specify sorting options available on a column.
impl Sortable for PersonField {
fn sort_by(&self) -> Option<SortBy> {
// We can choose column specifics but this is good for the minimum.
SortBy::increasing_or_decreasing()
}
}
#[inline_props]
fn OurMinimalExampleTable(cx: Scope) -> Element {
// Set up Dioxus state hooks. *Must* be called every time in the same order
let sorter = use_sorter::<PersonField>(cx);
// Obtain our data. Either passed via props or pulled from a server
let mut data = load_data();
// Sort our data. This is optional but needed to apply the sort
sorter.sort(data.as_mut_slice());
// Render our table like normal.
cx.render(rsx! {
table {
thead {
tr {
// Note that we use `Th` instead of `th`.
// We could customise `th` by using `ThStatus` instead.
// Or use `UseSorter::toggle_field` elsewhere to lift
// the sorter out of the table entirely.
Th { sorter: sorter, field: PersonField::Name, "Name" }
Th { sorter: sorter, field: PersonField::Age, "Age" }
}
}
tbody {
// Iterate on our sorted data.
// If we didn't want sortable tables, this could easily be a
// `ul { li { ... } }` instead.
for person in data.iter() {
tr {
td { "{person.name}" }
td { "{person.age}" }
}
}
}
}
})
}
依赖项
约 2-3MB
约 55K SLoC