组件 API

本文档介绍了组件系统的核心 API,包括组件的导入、属性声明、事件管理等,帮助开发者更高效地构建和管理自定义组件。

import!

import! 宏用于引入自定义组件,使其可以在当前作用域内使用。

用法

1import! {
2    crate::moudle::to::component;
3}

示例

在结构中使用 import! 引入 Rust 组件:

1<template>
2    <component name="MyView2">
3        <Header></Header>
4        <MyView1></MyView1>
5    </component>
6</template>
7
8<script>
9import! {
10    crate::views::my_view1::*;
11    crate::components::header::*;
12}
13</script>

#[component]

对于自定义组件,我们需要使用#[component]宏进行组件的属性声明,但并不是所有的类型都是允许的,能够在属性中使用的类型需要实现Defaulttrait, 自定义struct和enum则需要使用#[prop]进行标注。

1<script>
2#[component]
3pub struct MyView{
4    name: String
5}
6</script>

#[prop]

#[prop] 宏用于定义组件的属性(Props)。我们需要使用 #[prop] 宏来声明属性,以便实例化组件时进行赋值。

限制

不是所有的类型都可以作为 prop 使用,只有实现了 Default trait 的类型才能用于属性声明。

示例

1<script>
2#[component]
3pub struct MyView{
4    user: User,
5    auth: Auth
6}
7
8#[prop]
9#[derive(Debug, Clone)]
10pub struct User{
11    name: String
12}
13
14impl Default for User{
15    fn default() -> Self{
16        Self{ name: "John" }
17    }
18}
19
20#[prop]
21#[derive(Default, Clone, Copy, Debug)]
22pub enum Auth{
23    #[default]
24    Custom,
25    User,
26    Remote,
27    Other
28}
29</script>

get|set 方法

所有组件内声明的并在模版中进行绑定的属性都会自动生成对应的 getset 方法。请使用 get|set 方法来访问和修改属性值,否则会导致双向绑定失效。

例如,上述 MyView 结构体会自动生成以下方法:

  • fn get_user(&self) -> User;
  • fn set_user(&mut self, value: User) -> ();
  • fn get_auth(&self) -> Auth;
  • fn set_auth(&self, value: Auth) -> ();

Default trait

Default trait 用于初始化组件实例的属性值。

示例

1<script>
2#[component]
3pub struct MyView {
4    name: String,
5}
6
7impl Default for MyView{
8    fn default() -> Self{
9        Self{
10            name: "John".to_string(),
11        }
12    }
13}
14</script>

在后续的代码中,您可以像实现impl一样实现组件方法和回调函数,例如:

1impl MyView{
2    fn click_btn(&mut self) -> (){
3        let name = self.get_name();
4        self.set_name("Alice".to_string());
5    }
6}

#[event]

自定义组件默认情况下不会触发任何事件,若要使用事件系统,需要使用 #[event] 宏进行事件声明。

要求

  • 事件必须使用 #[event] 进行标记。
  • 事件类型必须派生 DebugClone trait。

示例

1#[event]
2#[derive(Debug, Clone)]
3pub enum MyViewEvent {
4    Clicked,
5    Changed(String),
6}

在上述示例中,我们定义了 MyViewEvent 事件类型,其中:

  1. Clicked:无参数的点击事件。
  2. Changed(String):携带 String 参数的变更事件。

c_ref!

c_ref! 宏用于根据组件 id 获取组件引用,便于直接操作组件实例的引用。

示例

1<template>
2    <component name="MyView">
3        <label id="my_label" text="'Hello'"></label>
4        <button id="my_btn" @clicked="get_label_text()">
5            <label as_prop="slot" text="'get my label text'"></label>
6        </button>
7    </component>
8</template>
9
10<script>
11#[component]
12struct MyView{}
13
14impl MyView{
15    fn get_label_text(&mut self) {
16        let label = c_ref!(my_label);
17        let label_text = label.get_text();
18        println!("label text is: {}", label_text);
19    }
20}
21</script>

active!

active! 宏用于触发组件内部定义的事件,并将其传递给外部组件进行回调处理。

示例

组件MyView

1#[event]
2#[derive(Debug, Clone)]
3pub enum MyViewEvent {
4    Clicked,
5    Changed(String),
6}
7
8impl MyView{
9    fn click_view(&self) {
10        let _ = active!(MyViewEvent::Clicked);
11    }
12
13    fn change_view(&self) {
14        active!(MyViewEvent::Changed, "changed!".to_string());
15    }
16}

组件FatherView

FatherView 组件监听 MyView 的事件:

1<template>
2    <component name="FatherView">
3        <MyView 
4            @clicked="my_view_clicked()" 
5            @changed="my_view_changed()">
6        </MyView>
7    </component>
8</template>
9
10<script>
11#[component]
12struct FatherView{}
13
14impl FatherView{
15    fn my_view_clicked(&self) {
16        dbg!("my_view_clicked!");
17    }
18
19    fn my_view_changed(&self, param: impl EventParam) {
20        dbg!(param);
21    }
22}
23</script>