《进击吧!Blazor!》第一章 5.组件开发 (3)

可以定义 RenderFragment<TValue> 类型的组件参数来定义支持参数的模板。

<!--组件代码--> @foreach (var item in Items) { <h4>@Title(item) is Superior!</h4> } @code{ [Parameter] public RenderFragment<string> Title { get; set; } [Parameter] public IReadOnlyList<string> Items { get; set; } } <!--组件使用--> <Component Items="items"> <Title Context="item"> <strong>@item</strong> </Title> </Component> @code{ List<string> items = new List<string> { ".Net", "C#", "Blazor" }; }

在这里插入图片描述


组件使用时通过IReadOnlyList<string> Items属性将内容传入组件,组件内部使用@foreach (var item in Items)将集合循环呈现,@Title(item)确定了插入位置,且给模板传入item的值,再外部通过Context="item"接收参数,最终实现模板的呈现。

6.生命周期

Blazor 框架包括同步和异步生命周期方法。一般情况下同步方法会先与异步方法执行。
我们可以重写生命周期方法的,以在组件初始化和呈现期间对组件执行其他操作。

组件初始化

组件状态改变

在这里插入图片描述

组件销毁

ToDo应用组件化改造 任务信息

重要任务不论是否是今天,我们都需要便捷的查看,所以我们需要做一个“重要任务”的页面。
这个页面显示内容和“我的一天”非常相似,所以我们可以抽象出一个TaskItem.razor组件,组件的Html以及样式基本是从ToDay.razor组件迁移过来。

<Card Bordered="true" Size="small"> <div> @{ var finishClass = new ClassMapper().Add("finish").If("unfinish", () => Item.IsFinish == false); } <div @onclick="OnFinishClick"> <Icon Type="check" Theme="outline" /> </div> <div @onclick="OnCardClick"> @if (TitleTemplate != null) { @TitleTemplate } else { <AntDesign.Text Strong> @Item.Title</AntDesign.Text> <br /> <AntDesign.Text Type="@TextElementType.Secondary"> @Item.Description </AntDesign.Text> } </div> <div @onclick="OnDelClick"> <Icon Type="rest" Theme="outline" /> </div> <div> @Item.PlanTime.ToShortDateString() <br /> @{ int? days = (int?)Item.Deadline?.Subtract(DateTime.Now.Date).TotalDays; } <span#ccc", _ when days > 0 => "#ffd800", _ => "#ff0000" })"> @Item.Deadline?.ToShortDateString() </span> </div> @if (ShowStar) { <div @onclick="OnStarClick"> <Icon Type="star" Theme="@(Item.IsImportant ? "fill" : "outline")" /> </div> } </div> </Card> public partial class TaskItem { //任务内容 [Parameter] public TaskDto Item { get; set; } //完成图标事件 [Parameter] public EventCallback<TaskDto> OnFinish { get; set; } public async void OnFinishClick() { if (OnFinish.HasDelegate) await OnFinish.InvokeAsync(Item); } //条目点击事件 [Parameter] public EventCallback<TaskDto> OnCard { get; set; } public async void OnCardClick() { if (OnCard.HasDelegate) await OnCard.InvokeAsync(Item); } //删除图标事件 [Parameter] public EventCallback<TaskDto> OnDel { get; set; } public async void OnDelClick() { if (OnDel.HasDelegate) await OnDel.InvokeAsync(Item); } //重要图标事件 [Parameter] public EventCallback<TaskDto> OnStar { get; set; } public async void OnStarClick() { if (OnStar.HasDelegate) await OnStar.InvokeAsync(Item); } //是否相似重要图标 [Parameter] public bool ShowStar { get; set; } = true; //支持标题模板 [Parameter] public RenderFragment TitleTemplate { get; set; } }

@if (TitleTemplate != null) 如果外部传入了模板,那么就是显示模板,否则就使用默认格式显示。

新建任务

在“重要任务”和“我的一天”中均有添加任务的功能,我们也将他们抽象成NewTask.razor组件。

<Divider Text="新任务"></Divider> @if (newTask != null) { <Spin Spinning="isNewLoading"> <div> <DatePicker Picker="@DatePickerType.Date" @bind-Value="@newTask.PlanTime" /> <Input @bind-Value="@newTask.Title" OnkeyUp="OnInsertKey" /> @if(ChildContent!=null ) { @ChildContent(newTask) } </div> </Spin> } public partial class NewTask { [Inject] public MessageService MsgSrv { get; set; } [Inject] public HttpClient Http { get; set; } [Parameter] public EventCallback<TaskDto> OnInserted { get; set; } [Parameter] public Func<TaskDto> NewTaskFunc { get; set; } [Parameter] public RenderFragment<TaskDto> ChildContent { get; set; } //新的任务 TaskDto newTask { get; set; } private bool isNewLoading { get; set; } protected override void OnInitialized() { newTask = NewTaskFunc?.Invoke(); base.OnInitialized(); } async void OnInsertKey(KeyboardEventArgs e) { if (e.Code == "Enter") { if (string.IsNullOrWhiteSpace(newTask.Title)) { MsgSrv.Error($"标题必须填写"); return; } isNewLoading = true; var result = await Http.PostAsJsonAsync<TaskDto>($"api/Task/SaveTask", newTask); if (result.IsSuccessStatusCode) { newTask.TaskId = await result.Content.ReadFromJsonAsync<Guid>(); await Task.Delay(1000); if (OnInserted.HasDelegate) await OnInserted.InvokeAsync(newTask); newTask = NewTaskFunc?.Invoke(); } else { MsgSrv.Error($"请求发生错误 {result.StatusCode}"); } isNewLoading = false; StateHasChanged(); } } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpsgjf.html