如何封装支持Ref、值绑定与失焦事件的Blazor Input组件
封装带逻辑的Tailwind风格Blazor Input组件解决方案
针对你提到的封装带聚焦、双向绑定和失焦逻辑的input组件需求,这里提供一个符合Blazor组件设计规范的实现方案,完美适配你之前的Tailwind组件封装思路:
1. 创建可复用的TimeInput组件
新建TimeInput.razor文件,封装input元素及核心逻辑,同时对外暴露可配置参数:
<!-- Tailwind类名固化在组件内,也可通过AdditionalClasses扩展 --> <input class="input-text nomargin centerInputContentVertical @AdditionalClasses" type="time" @ref="_internalInputRef" @bind-value="Value" @bind-value:event="oninput" @onblur="TriggerBlurCallback"> @code { // 组件内部维护input元素引用 private ElementReference _internalInputRef; /// <summary> /// 暴露给父组件的input元素引用(用于聚焦等操作) /// </summary> public ElementReference InputElement => _internalInputRef; /// <summary> /// 双向绑定的时间值(DateTime类型) /// </summary> [Parameter, EditorRequired] public DateTime Value { get; set; } /// <summary> /// 值变更回调,实现双向绑定 /// </summary> [Parameter, EditorRequired] public EventCallback<DateTime> ValueChanged { get; set; } /// <summary> /// 用于表单验证的表达式,必须配合双向绑定使用 /// </summary> [Parameter] public Expression<Func<DateTime>> ValueExpression { get; set; } /// <summary> /// 失焦时触发的父组件回调方法 /// </summary> [Parameter, EditorRequired] public EventCallback<FocusEventArgs> OnBlur { get; set; } /// <summary> /// 可选:扩展类名,支持父组件自定义样式 /// </summary> [Parameter] public string AdditionalClasses { get; set; } = string.Empty; /// <summary> /// 封装聚焦方法,父组件可直接调用 /// </summary> public ValueTask FocusAsync() { return _internalInputRef.FocusAsync(); } private async Task TriggerBlurCallback(FocusEventArgs args) { // 触发父组件传入的失焦逻辑 if (OnBlur.HasDelegate) { await OnBlur.InvokeAsync(args); } } }
2. 父组件中使用该组件
在需要的页面/组件中引入TimeInput,传入你的业务逻辑参数:
<!-- 使用示例 --> <TimeInput @bind-Value="blazorStartTime" OnBlur="HandleStartTimeSet" @ref="_timeInputComponent" AdditionalClasses="w-full"> </TimeInput> @code { // 子组件实例引用,用于调用聚焦方法或获取input元素 private TimeInput _timeInputComponent; // 绑定的时间值(与原逻辑一致) private DateTime blazorStartTime = DateTime.Now; // 原有的失焦处理逻辑 private void HandleStartTimeSet(FocusEventArgs args) { // 计算TimeSpan并更新ViewModel的业务逻辑 TimeSpan selectedTime = blazorStartTime.TimeOfDay; // ... 你的具体业务代码 } // 示例:调用子组件的聚焦方法 private async Task FocusTimeInput() { await _timeInputComponent.FocusAsync(); } }
核心设计说明
- 元素引用管理:组件内部维护input的引用,通过公共属性或封装的
FocusAsync方法暴露给父组件,避免直接操作DOM的耦合问题。 - 双向绑定兼容:遵循Blazor标准双向绑定模式,使用
Value+ValueChanged+ValueExpression参数组合,确保@bind-Value语法正常工作,自动同步时间值。 - 回调逻辑解耦:通过
OnBlur参数接收父组件的业务逻辑,组件只负责触发事件,不处理具体业务,保证组件的通用性。 - 样式扩展性:保留
AdditionalClasses参数,支持父组件追加Tailwind类名,和你之前的RapportGrid组件风格统一。
内容的提问来源于stack exchange,提问作者Aka3D
相关产品推荐
相关产品推荐

