我目前正在使用MudBrazor,非常喜欢它。
然而,我发现自己反复添加一些东西到组件中,比如CancellationTokens,正在自己自定义模板。
有没有一种方法可以完全继承/扩展现有组件?
一种选择是创建一个新组件,其中包含我要修改的组件的实例,并将所有参数添加到我的组件中,并将它们映射回原始组件,但我觉得必须有更好的方法。
属性飞溅对于围绕其他组件创建包装器或更高级别的抽象非常方便:
<MudTextField Variant="@Variant" @attributes="@OtherAttributes"></MudTextField>
@code {
[Parameter(CaptureUnmatchedValues = true)]
public Dictionary<string, object> OtherAttributes { get; set; }
[Parameter]
// can even set your own defaults
public Variant Variant { get; set; } = "Variant.Filled"
}
您还可以创建自己的基本组件,并将@inherits
用于共享逻辑和参数。
您可以像继承任何其他非密封类一样继承blazor组件
using Microsoft.AspNetCore.Components;
using MudBlazor;
namespace MyMudBlazor;
public partial class MyMudButton : MudButton
{
[Parameter] public bool IsEnabled
{
get { return !base.Disabled; }
set { base.Disabled = !value; }
}
}
继承
听起来你很可能想在自己的新组件中@继承MudBlazor组件。这基本上允许您使用MudBrazor组件作为新类/组件的基类,避免了重新定义MudBra佐r组件已经定义的所有参数。
这可以在C#或剃须刀中完成。这里有一个剃刀示例OutlinedMudButton.razor
,它允许用户仍然设置除Variant
参数之外的所有常用MudButton参数:
@inhertis MudButton
@code {
// Hide the MudButton's Variant parameter so it can not be changed by users.
protected new Variant Variant { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
base.Variant = Variant.Outlined;
}
}
这篇博客文章展示了一个完整的示例,说明如何继承组件以扩展它、更改默认参数设置、向其中添加新的UI元素、隐藏/禁用基本组件的参数,以及可能更改其功能。如果你想在组件周围添加新的UI元素,你可以使用下面的代码行来显示你从中继承的基本组件,并在它周围放置新的UI元件
@{
// Display the base component that we are inheriting from.
base.BuildRenderTree(__builder);
}
组成
根据您的用例,您可能希望使用组合而不是继承,方法是创建一个新组件,该组件只包含要装饰的MudBlazor组件的一个实例。这可能更容易或更合适,尤其是如果您想隐藏MudBlazor组件的许多参数,这样用户就无法更改它们。请注意,如果您像其他答案/注释中建议的那样使用属性splatting,那么缺点是您的组件不会为MudBlazor组件的所有参数提供编辑器智能感知。
这里是另一个剃刀示例OutlinedMudButton.razor
,它创建了一个带有Outlined MudButton的组件,其中用户唯一可以设置的是按钮Text
:
<MudButton Variant="Variant.Outlined">@Text</MudButton>
@code {
[Parameter]
public string Text { get; set;}
}
我经常使用的一个快捷方式是创建一个不带标记的.razor
组件。它使用我想要的任何服务,添加事件处理程序等等。因此,我有一个处理业务逻辑的拖入子组件,而不是继承。如果它也有方法,那么我会在组件的标记中添加@ref。我的许多页面看起来是这样的:
<FontSizeUtility UserId = @UserId />
<TimerUtility @ref=MyTimer TimerTicker = HandleTimerTick />
@code{
TimerUtility MyTimer = new();
. . .
async Task HandleTimerTick(){
}
}