Blazor 的 EventCallback 是父子组件通信的核心机制,本质是类型安全、异步友好的委托封装,专为 WebAssembly 和 Server 渲染场景设计。它不是传统 .NET 多播事件,而是单向、可 await 的回调通道——用对了,组件联动就清晰可控;用错了,容易卡 UI 或收不到值。
定义并暴露 EventCallback(子组件里)
在子组件中,用
[Parameter]声明一个
EventCallback<t></t>属性,作为“出口”。T 是你想传给父组件的数据类型,可以是
string、
int、
MouseEventArgs,甚至自定义类。 写法示例:
[Parameter] public EventCallback<book> OnAddToCartClicked { get; set; }</book>
必须加 [Parameter],否则父组件无法绑定 不推荐用
EventCallback(无泛型版),除非你真不需要传参
触发回调(子组件内部调用)
当子组件内发生需要通知父组件的动作时(比如按钮点击、输入完成、状态切换),调用
InvokeAsync()。 传参调用:
await OnAddToCartClicked.InvokeAsync(selectedBook);无参调用:
await OnClick.InvokeAsync();一定要用
await,因为它是异步的;Blazor 会自动触发 UI 刷新 调用前建议检查是否已注册:
if (OnAddToCartClicked.HasDelegate) { ... },避免空引用异常
接收并处理回调(父组件里)
父组件在使用子组件时,通过属性绑定把一个方法“塞进去”,这个方法就是事件的处理逻辑。
绑定写法:<bookcard book="book" onaddtocartclicked="HandleAddToCart"></bookcard>处理方法可以是同步或异步:
private void HandleAddToCart(Book b) { _cart.Add(b); } 或 private async Task HandleAddToCart(Book b) { await SaveToApi(b); }
方法签名必须和子组件声明的 EventCallback<t></t>类型匹配,否则编译报错
常见搭配与注意事项
EventCallback 不是孤立存在的,常配合其他模式一起用:
MudBlazor 等第三方组件都基于它实现交互,比如<mudbutton onclick="OnClickHandler"></mudbutton>原生 DOM 事件(如
@onmouseover)可直接绑定,但若要透传到父级,仍需封装成 EventCallback 不能用接口直接约束 EventCallback(
IEventCallback是 internal 的),想复用逻辑建议用基类或抽象组件 它只支持单播——一个 EventCallback 只能绑定一个处理方法;如需广播,得自己用委托链(
Func<t task> += handler1; += handler2;</t>)再包装成 EventCallback
基本上就这些。核心就三点:子组件定义出口、子组件主动触发、父组件提供入口。不复杂但容易忽略细节,比如忘了 await、类型不匹配、或没加 [Parameter]。
