组件 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>

#[prop]

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

限制

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

示例

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

get|set 方法

所有 #[prop] 标记的属性都会自动生成对应的 getset 方法。建议使用 get|set 方法来访问和修改属性值,否则可能会导致双向绑定失效。

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

  • fn get_name(&self) -> String;
  • fn set_name(&mut self, value: String) -> ();

default_prop!

default_prop! 宏用于初始化组件实例的属性值。

示例

1<script>
2#[prop]
3pub struct MyView {
4    name: String,
5}
6
7let mut prop = default_prop! {
8    MyView {
9        name: "John".to_string(),
10    }
11};
12</script>

在后续的代码中,您可以使用 prop 访问 get|set 方法,例如:

1let name = prop.get_name();
2prop.set_name("Alice".to_string());
DANGER

propget|set 方法目前不支持在 macro_expr(宏表达式)中使用,例如:

1println!("name is: {}", prop.get_name());

#[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>
11fn get_label_text() {
12    let label = c_ref!(my_label);
13    let label_text = label.get_text();
14    println!("label text is: {}", label_text);
15}
16</script>

active!

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

示例

组件MyView

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

组件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>
11fn my_view_clicked() {
12    dbg!("my_view_clicked!");
13}
14
15fn my_view_changed(param: impl EventParam) {
16    dbg!(param);
17}
18</script>