详解 Blazor 组件传值

父子组件传值

Blazor 中,组件之间的通信可以通过 [Parameter] 参数和 EventCallback<T> 事件回调实现。下面分别给出 父组件传递值给子组件子组件传递值给父组件 的简单示例。


1.1 父组件传递值给子组件

步骤:

  • 在子组件中定义 public 属性,并使用 [Parameter] 特性标记。
  • 在父组件中通过绑定属性将值传递给子组件。

示例代码:

子组件 ChildComponent.razor
<h3>子组件收到的值: @Message</h3>

@code {
    [Parameter]
    public string Message { get; set; }
}
父组件 ParentComponent.razor
<ChildComponent Message="@message" />

@code {
    private string message = "Hello from parent!";
}

1.2 子组件传递值给父组件

步骤:

  • 使用 EventCallback<T> 实现子组件向父组件传值。
  • 子组件触发事件并携带数据,父组件监听该事件并处理数据。

示例代码:

子组件 ChildComponent.razor
<button @onclick="SendMessage">发送消息给父组件</button>

@code {
    [Parameter]
    public EventCallback<string> OnMessageSent { get; set; }

    private async Task SendMessage()
    {
        await OnMessageSent.InvokeAsync("这是来自子组件的消息");
    }
}
父组件 ParentComponent.razor
<ChildComponent OnMessageSent="HandleMessage" />
<p>收到子组件的消息: @receivedMessage</p>

@code {
    private string receivedMessage;

    private void HandleMessage(string message)
    {
        receivedMessage = message;
    }
}

1.3 总结

通信方向实现方式
父组件 → 子组件使用 [Parameter] 传递属性值
子组件 → 父组件使用 EventCallback<T> 触发事件

这种方式可以满足大多数 Blazor 组件间的基本通信需求。


级联组件传值

Blazor 中,级联传值(Cascading Communication) 可以通过以下几种方式实现:

  1. 使用 CascadingParameter 实现层级组件传值
  2. 使用 CascadingValue 组件包裹子树,并向下传递数据

下面是一个 三层级组件传值的完整示例(父 → 子 → 孙)


2.1 使用 CascadingValueCascadingParameter

示例结构

ParentComponent.razor
└── ChildComponent.razor
    └── GrandChildComponent.razor

Ⅰ. 父组件:ParentComponent.razor

@page "/parent"

<CascadingValue Value="@message">
    <ChildComponent />
</CascadingValue>

@code {
    private string message = "来自父组件的消息";
}

Ⅱ. 子组件:ChildComponent.razor

<h4>子组件收到消息: @cascadeMessage</h4>
<GrandChildComponent />

@code {
    [CascadingParameter]
    public string cascadeMessage { get; set; }
}

Ⅲ. 孙组件:GrandChildComponent.razor

<h5>孙组件收到消息: @cascadeMessage</h5>

@code {
    [CascadingParameter]
    public string cascadeMessage { get; set; }
}

2.2 运行效果

访问 /parent 路由后,页面将显示如下内容:

子组件收到消息: 来自父组件的消息
孙组件收到消息: 来自父组件的消息

说明:

  • CascadingValue 将值从父组件广播给其所有嵌套子组件。
  • 所有子组件通过 [CascadingParameter] 接收值,无需手动逐层传递。

2.3 注意事项

注意点说明
类型匹配CascadingValue 的类型必须与接收组件的 CascadingParameter 类型一致
多个值可以使用多个 CascadingValue 包裹不同值,或使用对象封装多个字段
性能影响不建议过度使用级联参数,避免造成上下文污染和性能问题

2.4 进阶用法:传递对象而非基本类型

<CascadingValue Value="@userContext">
    <ChildComponent />
</CascadingValue>

@code {
    private UserContext userContext = new UserContext { Name = "Alice", Role = "Admin" };
}

public class UserContext {
    public string Name { get; set; }
    public string Role { get; set; }
}

子组件中接收:

[CascadingParameter]
public UserContext userContext { get; set; }

blazor

如需更复杂的通信(如跨层级双向绑定),可以结合 EventCallback 或使用状态管理库(如 Fluxor)。

更复杂的通信

Blazor 中,当组件层级较深或需要实现 跨层级双向绑定通信 时,推荐使用以下两种方式:


✅ 方案一:结合 EventCallback 实现跨层级通信

场景说明:

  • 组件层级嵌套较深(如 父 → 子 → 孙)。
  • 需要从最内层子组件向顶层组件传递数据,并同步更新状态。

示例结构:

ParentComponent.razor
└── ChildComponent.razor
    └── GrandChildComponent.razor

1. 父组件:ParentComponent.razor

@page "/parent"

<h3>父组件显示的值: @sharedValue</h3>

<ChildComponent OnValueChanged="UpdateValue" />

@code {
    private string sharedValue = "初始值";

    private void UpdateValue(string newValue)
    {
        sharedValue = newValue;
    }
}

2. 子组件:ChildComponent.razor

<GrandChildComponent OnValueChanged="OnValueChanged" />

@code {
    [Parameter]
    public EventCallback<string> OnValueChanged { get; set; }
}

3. 孙组件:GrandChildComponent.razor

<input @bind="inputValue" />
<button @onclick="SendValueToParent">发送到父组件</button>

@code {
    private string inputValue = "默认输入";

    [Parameter]
    public EventCallback<string> OnValueChanged { get; set; }

    private async Task SendValueToParent()
    {
        await OnValueChanged.InvokeAsync(inputValue);
    }
}

运行效果:

  1. 在孙组件中修改输入框内容并点击按钮;
  2. 消息会逐级上传至父组件;
  3. 父组件中的 sharedValue 被更新并重新渲染。

✅ 方案二:使用状态管理库 Fluxor 实现全局共享状态(推荐)

优势:

  • 避免层层传递参数和事件回调;
  • 实现组件间真正的“双向绑定”;
  • 支持集中管理应用状态,提升可维护性。

安装 Fluxor

通过 NuGet 安装:

dotnet add package Fluxor --version 6.6.0

注册服务(在 Program.cs 中):

builder.Services.AddFluxor(options =>
    options.ScanAssemblies(typeof(Program).Assembly));

1. 创建 State 类:CounterState.cs

public class CounterState(int count)
{
    public int Count { get; } = count;
}

2. 创建 Feature 和 Reducer:CounterFeature.cs

public class CounterFeature : Feature<CounterState>
{
    public override string GetName() => "Counter";

    public override CounterState GetInitialState() => new(0);
}

public record IncrementAction();
public record DecrementAction();

public class CounterReducer
{
    [ReducerMethod]
    public static CounterState Increment(CounterState state, IncrementAction action) =>
        new(state.Count + 1);

    [ReducerMethod]
    public static CounterState Decrement(CounterState state, DecrementAction action) =>
        new(state.Count - 1);
}

3. 创建 Store 并使用(任意组件中)

使用 Store 的组件示例:CounterComponent.razor
@inject IStore store;
@inject IDispatcher dispatcher;

<p>当前计数: @counterState.Value.Count</p>
<button @onclick="Increment">+1</button>
<button @onclick="Decrement">-1</button>

@code {
    private IState<CounterState> counterState;

    protected override void OnInitialized()
    {
        counterState = store.GetState<CounterState>();
    }

    private void Increment() => dispatcher.Dispatch(new IncrementAction());
    private void Decrement() => dispatcher.Dispatch(new DecrementAction());
}

运行效果:

  • 多个组件都可以访问和修改同一个 Count 值;
  • 所有监听该状态的组件都会自动刷新;
  • 实现了真正的跨层级、双向绑定通信。

🧠 总结对比

方式适用场景优点缺点
EventCallback层级不深 / 单向/双向传值简单直接层级多时繁琐
CascadingParameter同一树状结构下传值快速广播只能读取,不能双向绑定
Fluxor全局状态共享 / 复杂交互状态统一管理,解耦组件初期配置复杂

✅ 推荐实践

  • 小型项目:使用 EventCallback & CascadingParameter
  • 中大型项目或需要跨组件共享状态:优先使用 Fluxor
  • 更高级需求可考虑配合 TimeWarp.StateMediatR

说明:

  • Blazor-State 已更名为 TimeWarp.State

相关 nuget 包资源:

  • Blazor-Statehttps://www.nuget.org/packages/Blazor-State/11.0.0-beta.36
  • TimeWarp.Statehttps://www.nuget.org/packages/TimeWarp.State/
  • MediatRhttps://www.nuget.org/packages/MediatR
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ChaITSimpleLove

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值