如何让Razor派生组件正确渲染基础组件至嵌套组件中?
Blazor派生组件无法渲染基础组件内容的解决方案
问题场景
尝试创建派生组件,将基础组件的内容包裹在另一个组件内部,但运行后仅显示包裹组件的内容,基础组件的内容完全不渲染。
相关代码示例
BaseComponent.razor
<h3>BaseComponent</h3>
AdornmentComponent.razor
<div> <h3>Top of Adornment</h3> @ChildContent <h3>Bottom of Adornment</h3> </div> @code { [Parameter] public RenderFragment ChildContent { get; set; } }
DerivedComponent.razor(原错误写法)
@inherits BaseComponent <AdornmentComponent> @{ base.BuildRenderTree(__builder); } </AdornmentComponent>
Test.razor
@page "/Test" <DerivedComponent />
预期渲染结果:
<h3>Top of Adornment</h3> <h3>BaseComponent</h3> <h3>Bottom of Adornment</h3>
实际渲染结果:
<h3>Top of Adornment</h3> <h3>Bottom of Adornment</h3>
问题原因
Blazor Razor组件编译后会自动生成BuildRenderTree方法,当派生组件使用@inherits并编写自己的Razor模板时,编译器会生成新的BuildRenderTree逻辑,不会自动调用基础组件的对应方法。直接在ChildContent中调用base.BuildRenderTree(__builder)无法正确触发基础组件的渲染,因为缺少组件生命周期中必要的上下文初始化步骤。
解决方法
方案一:在基础组件中暴露渲染片段
修改BaseComponent.razor,添加一个返回基础组件渲染内容的RenderFragment属性:
<h3>BaseComponent</h3> @code { // 暴露基础组件的渲染内容供派生组件使用 public RenderFragment BaseRenderContent => builder => base.BuildRenderTree(builder); }
修改DerivedComponent.razor,直接引用这个属性作为AdornmentComponent的ChildContent:
@inherits BaseComponent <AdornmentComponent> @BaseRenderContent </AdornmentComponent>
方案二:通过代码类重写BuildRenderTree
创建DerivedComponent.razor.cs文件,直接重写BuildRenderTree方法来控制渲染逻辑:
public class DerivedComponent : BaseComponent { protected override void BuildRenderTree(RenderTreeBuilder builder) { // 开启AdornmentComponent的渲染 builder.OpenComponent<AdornmentComponent>(0); // 将基础组件的内容作为ChildContent传递 builder.AddAttribute(1, nameof(AdornmentComponent.ChildContent), (RenderFragment)(childBuilder => base.BuildRenderTree(childBuilder))); // 结束AdornmentComponent的渲染 builder.CloseComponent(); } }
此时DerivedComponent.razor可以简化为(仅保留继承声明,无需额外Razor内容):
@inherits DerivedComponent
验证效果
使用任意一种方案后,访问/Test页面即可得到预期的渲染结果。
内容的提问来源于stack exchange,提问作者Ben Rubin
相关产品推荐
相关产品推荐

