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

如何在Blazor的Razor组件中引用其他Razor文件内容?

Blazor迭代列表时加载对应派生组件内容

早上好!
我谷歌搜了一整天都没找到结果(可能关键词不对),想知道有没有办法实现这个需求,或者最优方案是什么。

项目简化结构

  • ItemCollection.razor
    • ItemCollection.razor.cs
  • Element.razor
    • Element.razor.cs
  • Element
    • Item.razor
      • Item.razor.cs

现有组件代码

Element.razor

@namespace myns
@inherit ComponentBase

<style>
.element {
    height: @this.Height;
    width: @this.Width;

}
</style>

Element.razor.cs

namespace myns;

public partial class Element : ComponentBase
{
    public string ID { get; set; }
    public string Height { get; set; }
    public string Width { get; set; }
}

Item.razor

@namespace myns
@inherit Element

<style>
.item {
    background-color: aqua;
}
</style>

Item.razor.cs

namespace myns;

public partial class Item : Element
{
    // 修正语法错误:移除多余return
    public virtual string Class => "item";
}

DerivedItem1.razor

@namespace myns
@inherit Item

<style>
.item {
    background-color: black;
}
</style>
<!-- 修正Blazor点击事件写法:使用@onclick而非原生onclick -->
<div id="@base.ID" class="element @this.Class" @onclick="(e) => OnClick(this, e)"></div>

DerivedItem1.razor.cs

namespace myns;

public partial class DerivedItem1 : Item
{
    public override string Class => base.Class + " derived1";
    
    // 补充点击方法定义
    private void OnClick(object sender, EventArgs e)
    {
        // 自定义点击逻辑
    }
}

DerivedItem2.razor

@namespace myns
@inherit Item

<style>
.item {
    background-color: red;
}
</style>
<div id="@base.ID" class="element @this.Class" @onclick="(e) => OnClick(this, e)"></div>

DerivedItem2.razor.cs

namespace myns;

public partial class DerivedItem2 : Item
{
    public override string Class => base.Class + " derived2";
    
    private void OnClick(object sender, EventArgs e)
    {
        // 自定义点击逻辑
    }
}

Collection.razor

namespace myns;
@inherit ComponentBase

@foreach (var item in this.Items)
{
    @* 此处需根据item的派生类加载对应组件内容 *@
}

Collection.razor.cs

namespace myns;

public partial class Collection<T> : ComponentBase
{
    public List<T> Items { get; set; }
}

Root.razor

namespace myns;
@inherit ComponentBase

<!-- 引用Collection组件 -->
<Collection Items="@Items" />

Root.razor.cs

namespace myns;

public partial class Root : ComponentBase
{
    public Collection<Item> Items { get; set; } = new();
    
    protected override void OnInitialized()
    {
        // 示例数据初始化
        Items.Items.Add(new DerivedItem1 { ID = "item1", Height = "100px", Width = "100px" });
        Items.Items.Add(new DerivedItem2 { ID = "item2", Height = "100px", Width = "100px" });
    }
}

实现方案

方案1:类型匹配渲染(适合已知派生类型)

直接在Collection组件中通过类型判断渲染对应派生组件,逻辑直观:

修改Collection.razor:

@namespace myns;
@inherit ComponentBase

@foreach (var item in this.Items)
{
    if (item is DerivedItem1 derived1)
    {
        <DerivedItem1 ID="@derived1.ID" Height="@derived1.Height" Width="@derived1.Width" />
    }
    else if (item is DerivedItem2 derived2)
    {
        <DerivedItem2 ID="@derived2.ID" Height="@derived2.Height" Width="@derived2.Width" />
    }
    // 新增派生类型时,在此添加对应判断分支
}

方案2:基类定义RenderFragment(推荐,低耦合)

在Item基类中抽象渲染逻辑,让每个派生组件自行实现UI:

  1. 修改Item.razor.cs,添加抽象渲染片段:
namespace myns;

public partial class Item : Element
{
    public virtual string Class => "item";
    // 抽象渲染逻辑,由派生类实现
    public abstract RenderFragment RenderContent { get; }
}
  1. 在DerivedItem1.razor.cs中实现RenderContent:
namespace myns;

public partial class DerivedItem1 : Item
{
    public override string Class => base.Class + " derived1";
    
    public override RenderFragment RenderContent => builder =>
    {
        builder.OpenElement(0, "div");
        builder.AddAttribute(1, "id", base.ID);
        builder.AddAttribute(2, "class", $"element {this.Class}");
        builder.AddAttribute(3, "onclick", EventCallback.Factory.Create<MouseEventArgs>(this, () => OnClick(this, EventArgs.Empty)));
        builder.CloseElement();
    };
    
    private void OnClick(object sender, EventArgs e)
    {
        // 自定义点击逻辑
    }
}
  1. 同理修改DerivedItem2.razor.cs实现自身RenderContent。

  2. 修改Collection.razor调用渲染片段:

@namespace myns;
@inherit ComponentBase

@foreach (var item in this.Items)
{
    @item.RenderContent
}

方案3:动态组件渲染(适合未知/动态派生类型)

使用Blazor的DynamicComponent自动匹配类型渲染组件,扩展性最强:

修改Collection.razor:

@namespace myns;
@inherit ComponentBase

@foreach (var item in this.Items)
{
    <DynamicComponent Type="@item.GetType()" Parameters='new Dictionary<string, object>
    {
        { nameof(Element.ID), item.ID },
        { nameof(Element.Height), item.Height },
        { nameof(Element.Width), item.Width }
    }' />
}

新增派生类时无需修改Collection组件,自动适配渲染。


内容的提问来源于stack exchange,提问作者Ziemas Y.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:07:36