#dioxus #ui #gui #table-row #debugging

dxosus-sortable

为 Dioxus 提供可排序的表格和组件

3 个版本

0.1.2 2023 年 11 月 5 日
0.1.1 2023 年 7 月 2 日
0.1.0 2023 年 7 月 2 日

#992WebAssembly

LGPL-3.0 或更新

650KB
320

Dioxus 的可排序组件

Crates.io version docs.rs docs

创建任何类型的可排序表格(和其他组件)的 Dioxus

有关 英国首相 的完整示例(及相关代码)可供查看。完整文档和示例可在 https://docs.rs/dioxus-sortable 上找到


lib.rs:

Dioxus 的可排序组件

创建任何类型的可排序表格(和其他组件)的 Dioxus

重点是表格,但此库可以用于创建任何类型的可排序组件。您可以自定义表格。排序状态与数据分开保存。

在本文档中,您将看到类型 T 用于引用您要排序的数据类型。您还会看到 F,它应该是一个枚举,用于引用 T 的每个可排序字段。您的 F 枚举应实现 PartialOrdBy 以进行排序,以及 Sortable 以描述如何排序。

我们使用 PartialOrd 允许具有 NULL 语义的类型进行排序。这在有 f64::NAN 或“未知”字段时很有用。它允许我们处理更通用的案例。我们尽量保持排序语义与 SQL 的 ORDER BY 子句相同。

用法

  1. 创建一个您希望排序的 struct T。表格行。
  2. 创建一个描述 T 中每个可排序字段的 enum F
  3. F 实现 PartialOrdBy。这用于按 F 排序 T
  4. F 实现 Sortable。这用于描述如何对 F 进行排序。
  5. 在您的组件中调用 [use_sorter()] 并获取 UseSorter
  6. 调用 UseSorter::sort 来排序数据。这可以在等待数据到达时条件性地调用。
  7. 使用 [Th] 创建一个表格,或者使用 ThStatusUseSorter::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