Blazor 中父子组件通信主要靠参数传递(
@bind、
EventCallback)和
CascadingParameter,不需要状态管理库也能高效协作。
父传子:用 [Parameter] 接收属性
子组件定义 public 属性并加
[Parameter]特性,父组件像写 HTML 属性一样传值: 子组件(Child.razor)中写:[Parameter] public string Title { get; set; } = "默认标题"; 父组件中使用:
@parentTitle是父组件的字段或属性 支持双向绑定:子组件加
[Parameter] public string Value { get; set; } 和 [Parameter] public EventCallback<string> ValueChanged { get; set; }</string>,父组件用 @bind-Value="model.Text"即可同步更新
子传父:用 EventCallback 触发回调
这是最常用、最推荐的方式,本质是子组件“通知”父组件发生了什么:
子组件声明:[Parameter] public EventCallback@code中定义
void HandleChildSubmit(string msg) { ... }
注意:EventCallback支持泛型,可传任意类型(
EventCallback<int></int>、
EventCallback<mouseeventargs></mouseeventargs>等)
跨多层传递:用 CascadingParameter
适合主题、语言、认证上下文等需要贯穿多层组件的场景:
顶层组件(如 MainLayout.razor)包裹内容:[CascadingParameter] public User currentUser { get; set; }
注意:级联值变化时,所有监听它的组件会自动重新渲染(需确保值是引用类型或重写 ShouldRender控制)
不推荐但可行:通过服务共享状态
适用于复杂交互或多个非父子关系组件需协同的场景,但要小心生命周期和线程安全:
注册一个 scoped 服务(如SharedStateService),含
public event Action OnStateChanged;组件注入该服务,修改状态后触发事件,其他组件订阅并刷新 UI Blazor Server 下注意 SignalR 连接上下文;WebAssembly 下无此限制,但仍建议优先用前三种方式 避免在服务里直接操作 DOM 或依赖页面生命周期,保持纯逻辑
基本上就这些。多数场景用
[Parameter]+
EventCallback就够了,清晰、可控、易测试。CascadingParameter 是优雅的补充,服务共享则留作特殊需求兜底。
