You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor中如何渲染作为属性传入的子组件,有没有类似Angular ng-content的方案?

问题根因

你当前的写法输出类型名,是因为Blazor不会直接渲染手动实例化的ComponentBase对象,直接放到Razor模板中时只会调用其ToString()方法输出类型全名;同时手动实例化组件不符合Blazor的生命周期管理规则,无法完成参数绑定、事件注册等正常逻辑,属于错误用法。

Blazor中对应Angular ng-content的方案是使用RenderFragment实现内容插槽,我们可以基于这个特性实现同时兼容两种使用方式的Row组件。

最优实现方案(兼容两种使用方式)

1. 定义Column子组件

用于接收标记式写法中的列内容:

// Column.razor
@code {
    [CascadingParameter]
    private Row ParentRow { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    protected override void OnInitialized()
    {
        ParentRow?.AddColumn(this);
    }
}

2. 实现Row组件

// Row.razor
<div class="row">
    @* 渲染标记式传入的列 *@
    @foreach (var column in Columns)
    {
        <div class="col-6">
            @column.ChildContent
        </div>
    }
    @* 兼容编程式传入的列 *@
    @if (Columns.Count == 0)
    {
        @if (Column1 != null)
        {
            <div class="col-6">@Column1</div>
        }
        @if (Column2 != null)
        {
            <div class="col-6">@Column2</div>
        }
    }
</div>

@code {
    internal List<Column> Columns { get; set; } = new();

    [Parameter]
    public RenderFragment Column1 { get; set; }

    [Parameter]
    public RenderFragment Column2 { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    internal void AddColumn(Column column)
    {
        Columns.Add(column);
    }

    protected override void OnParametersSet()
    {
        Columns.Clear();
        ChildContent?.Invoke();
    }
}
两种使用方式示例

标记式写法(类似Angular ng-content效果)

和你要求的写法完全一致:

<Row>
    <Column>
        <Foo></Foo>
    </Column>
    <Column>
        <Bar></Bar>
    </Column>
</Row>

编程式传入组件写法

不需要手动实例化组件,直接定义渲染片段即可:

<Row Column1="@fooContent" Column2="@barContent"></Row>

@code {
    private RenderFragment fooContent = @<Foo />;
    private RenderFragment barContent = @<Bar />;
}
补充说明

如果需要动态渲染未知类型的组件,可以结合Blazor内置的DynamicComponent实现:

<Row Column1="@RenderComponent(typeof(Foo))" Column2="@RenderComponent(typeof(Bar))"></Row>

@code {
    private RenderFragment RenderComponent(Type componentType) 
        => @<DynamicComponent Type="@componentType" />;
}

内容的提问来源于stack exchange,提问作者Matthew Layton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 04:00:00