能否继承Blazor组件以添加属性并复用原有代码?
复用Blazor组件模板避免重复代码的方案
针对你遇到的继承组件后重复编写大量属性的问题,有两种简洁的解决思路,完全不用重复写原有组件的标签和属性:
方案一:基类封装属性收集逻辑,子类扩展
先改造你的MyComponent,把属性整理和组件渲染的逻辑拆分,让子类可以轻松扩展:
@* MyComponent.razor *@ <my-component @attributes="GetAllAttributes()"> @ChildContent </my-component> @code { [Parameter] public string Attr1 { get; set; } [Parameter] public string Attr2 { get; set; } [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object> AdditionalAttributes { get; set; } [Parameter] public RenderFragment ChildContent { get; set; } // 基类提供属性收集方法,子类可重写扩展 protected virtual Dictionary<string, object> GetAllAttributes() { var attributes = new Dictionary<string, object>(AdditionalAttributes ?? new()); attributes["attr1"] = Attr1; attributes["attr2"] = Attr2; return attributes; } }
然后在MoreDetailedComponent里,只需要新增属性并重写收集方法,直接复用基类的渲染逻辑:
@inherits MyComponent @* 直接渲染基类的模板内容,不用重复写<my-component>标签 *@ @base @code { [Parameter] public string Attr3 { get; set; } protected override Dictionary<string, object> GetAllAttributes() { // 先获取基类的所有属性,再添加新增的Attr3 var attributes = base.GetAllAttributes(); attributes["attr3"] = Attr3; return attributes; } }
方案二:基类封装渲染片段,子类复用
如果需要更灵活地控制组件渲染结构,可以把基类的组件渲染逻辑封装成RenderFragment:
@* MyComponent.razor *@ @code { [Parameter] public string Attr1 { get; set; } [Parameter] public string Attr2 { get; set; } [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object> AdditionalAttributes { get; set; } [Parameter] public RenderFragment ChildContent { get; set; } // 把原有组件渲染逻辑封装成可复用的片段 protected RenderFragment RenderBaseComponent(Dictionary<string, object> extraAttributes = null) { return (__builder) => { var mergedAttributes = new Dictionary<string, object>(AdditionalAttributes ?? new()); if (extraAttributes != null) { foreach (var kvp in extraAttributes) { mergedAttributes[kvp.Key] = kvp.Value; } } <my-component attr1="@Attr1" attr2="@Attr2" @attributes="mergedAttributes"> @ChildContent </my-component> }; } }
子类里直接调用这个方法并传入新增属性:
@inherits MyComponent @* 复用基类的渲染片段,传入新增的Attr3 *@ @RenderBaseComponent(new Dictionary<string, object> { { "attr3", Attr3 } }) @code { [Parameter] public string Attr3 { get; set; } }
这两种方案都能彻底避免重复编写数十个属性的问题,子类只需要关注新增的属性即可,完全复用基类的原有逻辑。
内容的提问来源于stack exchange,提问作者Luke Vo
相关产品推荐
相关产品推荐

