Blazor 应用基于组件,组件可以复用和嵌套。本文内容如下:
1. 组件类
所有组件都是继承 ComponentBase 组件基类,razor 文件默认继承 ComponentBase 类。 ComponentBase 实现组件的最低抽象,IComponent 接口。 ComponentBase 定义基本功能的组件属性和方法,例如,处理一组内置组件生命周期事件。
| //HTML 写法 |
| MyComponent.razor |
| |
| <div>Hello Known!div> |
| |
| class MyComponent : ComponentBase |
| { |
| protected override void BuildRenderTree(RenderTreeBuilder builder) |
| { |
| builder.Div("Hello Known!"); |
| } |
| } |
2. 组件嵌套
组件可以包含其他组件。用 HTML 语法,组件的标记类似于 HTML 标记,其中标记的名称是组件类型。
| //HTML 写法 |
| MyApp.razor |
| |
| <MyComponent /> |
C# 高级写法是通过扩展方法来实现的。
| |
| class MyApp : ComponentBase |
| { |
| protected override void BuildRenderTree(RenderTreeBuilder builder) |
| { |
| builder.Component().Build(); |
| } |
| } |
3. 组件参数
Blazor 应用是由若干组件拼搭而成,有些组件结构相同,数据不同,这样的组件就需要添加组件参数属性将数据传递给组件。组件参数需满足如下条件:
- 需要包含 [Parameter] 特性
- 必须是 public 的属性
| class MyComponent : ComponentBase |
| { |
| [Parameter] public string? Title { get; set; } |
| |
| [Parameter] public RenderFragment? ChildContent { get; set; } |
| |
| protected override void BuildRenderTree(RenderTreeBuilder builder) { ... } |
| } |
下面是组件参数的使用示例
| //HTML 写法 |
| MyApp.razor |
| |
| <div> |
| <MyComponent Title="组件1" /> |
| <MyComponent Title="组件2"> |
| 子内容呈现 |
| MyComponent> |
| div> |
| |
| class MyApp : ComponentBase |
| { |
| protected override void BuildRenderTree(RenderTreeBuilder builder) |
| { |
| builder.Div(attr => |
| { |
| builder.Component().Set(c => c.Title, "组件1").Build(); |
| builder.Component() |
| .Set(c => c.Title, "组件2") |
| .Set(c => c.ChildContent, b => b.Text("子内容呈现")) |
| .Build(); |
| }); |
| } |
| } |
4. 组件对象
组件是继承 ComponentBase 的一个类,如果要访问组件的方法,必须获取组件的对象实例。若要捕获组件对象实例,请执行以下操作:
- 向子组件添加 @ref 特性
- 定义与子组件类型相同的字段
| //HTML 写法 |
| MyApp.razor |
| |
| <div> |
| <MyComponent @ref="component" Title="组件1" /> |
| div> |
| |
| @code { |
| private MyComponent? component; |
| } |
C# 高级写法是在组件建造者 ComponentBuilder 类的 Build 方法中通过 AddComponentReferenceCapture 方法来捕获组件对象实例,该类不是 Blazor 框架类,后续将介绍该类的具体实现。
| |
| class MyApp : ComponentBase |
| { |
| private MyComponent? component; |
| |
| protected override void BuildRenderTree(RenderTreeBuilder builder) |
| { |
| builder.Div(attr => |
| { |
| builder.Component() |
| .Set(c => c.Title, "组件1") |
| .Build(value => component = value); |
| }); |
| } |
| } |