#table #leptos #table-column #data-provider #data-grid #data-sheet

leptos-struct-table

从结构定义生成一个完整的电池组包括的 Leptos 数据表格组件

27 个版本 (11 个破坏性更新)

0.12.0 2024 年 8 月 14 日
0.10.2 2024 年 6 月 7 日
0.9.1 2024 年 2 月 28 日
0.6.0 2023 年 11 月 2 日
0.3.2 2023 年 7 月 21 日

#156 in 网页编程

Download history 16/week @ 2024-04-29 9/week @ 2024-05-06 9/week @ 2024-05-13 133/week @ 2024-05-20 168/week @ 2024-05-27 579/week @ 2024-06-03 152/week @ 2024-06-10 29/week @ 2024-06-17 24/week @ 2024-06-24 28/week @ 2024-07-01 45/week @ 2024-07-08 24/week @ 2024-07-15 39/week @ 2024-07-22 30/week @ 2024-07-29 155/week @ 2024-08-05 138/week @ 2024-08-12

每月 364 次下载

MIT/Apache

670KB
2K SLoC

Leptos Struct Table

Crates.io Docs MIT/Apache 2.0 Build Status built with Codeium

轻松从结构创建 Leptos 表格组件。

Hero Image

功能

  • 易于使用 - 但功能强大。
  • 异步数据加载 - 数据异步加载。这允许从 REST API 或数据库等加载数据。
  • 选择 - 可关闭或单选/多选
  • 定制 - 您可以通过连接自己的用于渲染行、单元格、标题的组件来自定义表格的每个方面。有关更多信息,请参阅自定义渲染器
  • 无头 - 表格不应用默认样式。您可以完全自定义应用于表格的类。有关更多信息,请参阅类定制
  • 排序 - 可选。如果开启:点击列标题按该列排序表格。您甚至可以按多个列排序。
  • 虚拟化 - 只渲染可见行。这允许处理非常大的表格。
  • 分页 - 替代虚拟化,您可以分页表格。
  • 缓存 - 只加载和缓存可见行。
  • 编辑 - 可选。您可以提供自定义渲染器以编辑可编辑的单元格。有关更多信息,请参阅可编辑单元格

使用方法

use leptos::*;
use leptos_struct_table::*;

#[derive(TableRow, Clone)]
#[table(impl_vec_data_provider)]
pub struct Person {
    id: u32,
    name: String,
    age: u32,
}

fn main() {
    mount_to_body(|| {
        let rows = vec![
            Person { id: 1, name: "John".to_string(), age: 32 },
            Person { id: 2, name: "Jane".to_string(), age: 28 },
            Person { id: 3, name: "Bob".to_string(), age: 45 },
        ];

        view! {
            <table>
                <TableContent rows />
            </table>
        }
    });
}

服务器端渲染

要使用 Leptos 的服务器端渲染功能,您需要将 leptos-use 作为依赖项添加到您的 Cargo.toml,然后像以下那样进行配置。

[dependencies]
leptos-use = "<current version>"
# ...

[features]
hydrate = [
    "leptos/hydrate",
    # ...
]
ssr = [
    "leptos/ssr",
    # ...
    "leptos-use/ssr",
]

请参阅serverfn_sqlx 示例,了解带有 SSR 的工作项目。

数据提供者

如图初始使用示例所示,当您将 #[table(impl_vec_data_provider)] 添加到您的结构体中时,表格会自动为您生成数据提供者。然后您可以直接将一个 Vec<T> 传递给 rows 属性。内部实现了 TableDataProvider 特性,用于 Vec<T>

要利用具有缓存功能的异步部分数据加载的完整功能,您应该实现 PaginatedTableDataProvider 特性或自己实现 TableDataProvider 特性。这样做很简单。您选择哪个特性取决于您的数据源。如果您的数据源提供分页数据,例如许多REST API的情况,则应实现 PaginatedTableDataProvider。否则,您可能需要实现 TableDataProvider

请参阅 paginated_rest_datasource 示例serverfn_sqlx 示例,以查看实现这些特性的工作演示项目。

宏选项

可以使用 #[table(...)] 属性来自定义生成的组件。以下是一些可用的选项

结构体属性

以下属性可以应用于结构体本身。

  • sortable - 指定表格应可排序。这使得标题可点击以控制排序。您可以在 TableContent 组件的 sorting_mode 属性中指定两种排序模式
    • sorting_mode=SortingMode::MultiColumn(默认)允许表格按优先级排序多个列。
    • sorting_mode=SortingMode::SingleColumn"" 允许表格按单个列排序。点击另一个列将简单地替换排序列。有关更多信息,请参阅 simple 示例selectable 示例
  • classes_provider - 指定类提供者的名称。用于快速自定义应用于表格的所有类。为了方便起见,为主要的CSS框架提供了合理的预设。有关更多信息,请参阅 TableClassesProvidertailwind 示例
  • head_cell_renderer - 指定表头单元格渲染组件的名称。用于自定义表头单元格的渲染。默认为 DefaultTableHeaderRenderer。有关更多信息,请参阅 custom_renderers_svg 示例
  • impl_vec_data_provider - 如果提供,则自动为 Vec<ThisStruct> 实现 TableDataProvider,以便于本地数据的使用。有关更多信息,请参阅 simple 示例
  • row_type - 指定表格中行的类型。默认为此应用到的结构体。有关更多信息,请参阅 custom_type 示例

字段属性

这些属性可以应用于结构体中的任何字段。

  • class - 指定应用于字段列中每个单元格(头和体)的类。可以与 classes_provider 一起使用来自定义类。
  • head_class - 指定应用于字段列中头单元格的类。可以与 classes_provider 一起使用来自定义类。
  • cell_class - 指定应用于字段列中体单元格的类。可以与 classes_provider 一起使用来自定义类。
  • skip - 指定应跳过该字段。这对于不在表中显示的字段很有用。
  • skip_sort - 仅当在结构体上设置了 sortable 时适用。指定该字段不应用于排序。点击其标题将不会进行任何操作。
  • skip_header - 使字段的标题不在头行中显示。
  • title - 指定在头单元格中显示的标题。默认为将字段名转换为标题大小写(this_field 变为 "This Field")。
  • renderer - 指定单元格渲染组件的名称。用于自定义单元格的渲染。默认为 DefaultTableCellRenderer
  • format - 快速自定义单元格格式的快捷方式,而无需创建自定义渲染器。有关更多信息,请参阅下面的 Formatting
  • getter - 指定一个返回字段值的函数,而不是在渲染时直接访问字段。
  • none_value - 当 Option 类型为 None 时,指定要显示的显示值。默认为空字符串。

格式化

可以使用 format 属性来自定义单元格的格式。当您只想自定义一些基本的格式时,这是一个创建自定义渲染器的更简单替代方案。它是类型安全的,并且与应用格式的类型绑定。请参阅 CellValue 以及您要渲染的类型的相关类型,以查看选项列表

参见

功能

  • chrono - 为 chrono 包中的类型添加支持。
  • rust_decimal - 为 rust_decimal 包中的类型添加支持。
  • time - 为 time 包中的类型添加支持。
  • uuid - 为 uuid 包中的类型添加支持。

类自定义

可以通过在结构体上使用 classes_provider 属性来轻松地自定义类。您可以指定任何实现了 TableClassesProvider 特性的类型。请参阅该特性的文档以获取更多信息。您还可以查看 TailwindClassesPreset 以了解如何实现此功能。

示例

#[derive(TableRow, Clone)]
#[table(classes_provider = "TailwindClassesPreset")]
pub struct Book {
    id: u32,
    title: String,
}

字段获取器

有时您想显示的不是结构体的一部分,而是来自其他字段或完全不同的派生值。为此,您可以使用 FieldGetter 类型或 getter 属性。

让我们从 FieldGetter 开始,并查看一个示例

#[derive(TableRow, Clone)]
#[table(classes_provider = "TailwindClassesPreset")]
pub struct Book {
    id: u32,
    title: String,
    author: String,

    // this tells the macro that you're going to provide a method called `title_and_author` that returns a `String`
    title_and_author: FieldGetter<String>
}

impl Book {
    // Returns the value that is displayed in the column
    pub fn title_and_author(&self) -> String {
        format!("{} by {}", self.title, self.author)
    }
}

为了提供最大的灵活性,您可以使用 getter 属性。

#[derive(TableRow, Clone)]
#[table(classes_provider = "TailwindClassesPreset")]
pub struct Book {
    // this tells the macro that you're going to provide a method called `get_title` that returns a `String`
    #[table(getter = "get_title")]
    title: String,
}

impl Book {
    pub fn get_title(&self) -> String {
        format!("Title: {}", self.title)
    }
}

何时使用 FieldGettergetter 属性

类型为 FieldGetter<T> 的字段是一个虚拟字段,实际上在结构体上并不存在。内部上,FieldGetter 只是一个重新类型化的 PhantomData,因此在编译时被移除。因此,它不会增加内存使用。这意味着您应该仅用于纯派生数据。

应将 getter 属性用于结构体上实际存在的字段,但您希望在其渲染之前修改其值。

自定义渲染器

可以使用自定义渲染器来自定义表格的几乎所有方面。它们通过在 TableContent 组件的结构体或字段或属性上使用各种 ...renderer 属性来指定。要实现自定义渲染器,请查看以下默认渲染器。

在结构体级别上,您可以使用此属性

作为 `TableContent` 组件的属性,你可以使用以下功能

在字段级别上,你可以使用 renderer 属性。

它默认为 DefaultTableCellRenderer。适用于实现了标准库类型、流行crate的feature标志以及你自定义类型(如果你为它们实现了此trait)的任何实现了 CellValue 特性的类型。

示例

#[derive(TableRow, Clone)]
pub struct Book {
    title: String,
    #[table(renderer = "ImageTableCellRenderer")]
    img: String,
}

// Easy cell renderer that just displays an image from an URL.
#[component]
fn ImageTableCellRenderer<F>(
    class: String,
    #[prop(into)] value: MaybeSignal<String>,
    on_change: F,
    index: usize,
) -> impl IntoView
where
    F: Fn(String) + 'static,
{
    view! {
        <td class=class>
            <img src=value alt="Book image" height="64"/>
        </td>
    }
}

有关更详细的信息,请参阅 custom_renderers_svg 示例 以实现完全自定义。

可编辑单元格

你可能已经注意到了上面自定义单元格渲染器中的类型参数 F。这可以用于在单元格更改时发出事件。在最简单的情况下,你可以使用一个使用 `<input>` 的单元格渲染器。

#[derive(TableRow, Clone, Default, Debug)]
#[table(impl_vec_data_provider)]
pub struct Book {
    id: u32,
    #[table(renderer = "InputCellRenderer")]
    title: String,
}

// Easy input cell renderer that emits `on_change` when the input is changed.
#[component]
fn InputCellRenderer<F>(
    class: String,
    #[prop(into)] value: MaybeSignal<String>,
    on_change: F,
    index: usize,
) -> impl IntoView
where
    F: Fn(String) + 'static,
{
    view! {
        <td class=class>
            <input type="text" value=value on:change=move |evt| { on_change(event_target_value(&evt)); } />
        </td>
    }
}

// Then in the table component you can listen to the `on_change` event:

#[component]
pub fn App() -> impl IntoView {
    let rows = vec![Book::default(), Book::default()];

    let on_change = move |evt: ChangeEvent<Book>| {
        logging::log!("Changed row at index {}:\n{:#?}", evt.row_index, evt.changed_row);
    };

    view! {
        <table>
            <TableContent rows on_change />
        </table>
    }
}

请参阅 editable 示例 以获取完整的示例。

分页 / 虚拟化 / 无限滚动

此表格组件支持不同的显示加速策略。你可以通过 `TableContent` 组件的 `display_strategy` 属性来设置它们。

以下选项可用。请查看它们的文档以获取更多详细信息。

请查看分页示例以获取有关如何使用分页的更多信息。

国际化(I18n)

要使用leptos-i18n翻译表格的列标题,您可以启用"i18n"功能。结构体的字段名称用作键。

请查看i18n 示例

贡献

欢迎所有贡献。如果您有任何想法或问题,请提交问题或拉取请求。

Leptos 兼容性

包版本 兼容的 Leptos 版本
<= 0.2 0.3
0.3 0.4
0.4, 0.5, 0.6 0.5
0.7 – 0.12 0.6

依赖项

~22–35MB
~569K SLoC