15.组件生成周期,已由ComponentBase默认实现
- 1.设置参数前 SetParameterAsync
- 2.初始化 OnInitialized/OnInitializedAsync
- 3.设置参数后 OnParameterSet/OnParameterAsync
- 4.通知组件渲染 StateHasChanged
- 5.组件渲染呈现后 OnAfterRender/OnRenderAsync
- 6.组件删除前 DisPose
- Parent Re-render Or Update Paramters
- 判断是否渲染组件 ShouldRender
16.泛型组件
从架构的角度来考虑设计问题,组件本身是一个类,泛型支持会增加如同C#泛型类型一样的良好的复用性。
1.组件中泛型占位符的设计
用 @ytpeparam T
指令来声明 T 是类型占位符。在code中就可以使用 T 做为变量的类型定义,如:[Parameter]public T Shape{get;set;}
2.消费者对组件中泛型的使用
调用者直接在泛形组件中使用参数的型式来把具体类型传递给泛型组件,如:<GenaricComponent T="int" Shape="20">
,如果传了值20,则可以省略类型参数(T="int"
)的传递,C#可自动推导。
3.泛型约束
@ytpeparam T where T:class,IComparable<T>,new()
4.其他说明
泛型类型可声明多个。
官方组件默认几个典型的泛型实现的输入组件:
InputData, InputNumber, InputText
5.示例,做一个兼容所有C#基础类型的泛型组件
组件:GenaricInput.razor
@typeparam T
<input type="@InputType" value="@Value" @onchange="OnChange" />
@code
{
[Paramter]public T Value{get;set;}
[Paramter]public EventCallback<T> ValueChanged{get;set;}
string? FormatValueText{get;set;}
Task Onchange(ChangeEventArgs e)
{
var value=e.Value;//类型为 object
if(value is null)
return Task.CompeletedTask;
var newValue=Convert.ChangeType(value,typeof(T));
Value = (T)newValue;
FromatValueText=BindConverter.FormatValue(value)?.ToString();
return Task.CompeletedTask;
}
string? InputType => Value switch
{
double or float or int or decimal => "number",
DateOnly or Datetime or DateTimeOffset => "date",
_ => "text"
};
}
调用者页面:GenaricPage.razor
@Page "/genaricpage"
<GenaricInput @bind-Value="@Text" />
@code
{
double Text{get;set;}
}
- 注意:如果要从OnChange(ChangeEventArgs e)事件参数做类型转换,要使用
Convert.ChangeType(value,typeof(T))
如果要把值类型再显示在input组件文本框中,则需要使用绑定转换器BindConverter.FormatValue(value)?.ToString();