HarmonyOS6正式推送的消息刚出来那会儿,我其实没什么特别感觉,倒是有件事一直压在心里:我们自研的RcInput综合表单组件,经过了半年的反复打磨,终于在HarmonyOS6上跑稳了。这半年里,我从一开始觉得"不就是封装一个TextInput嘛",到后来发现输入框背后牵扯着校验、焦点、键盘避让、主题切换、性能优化一大堆问题,整个过程踩坑踩到怀疑人生。
这篇内容适合两类人:一类是在鸿蒙项目里被输入框和表单折腾过的同学,另一类是正准备做自己的组件库、想提前知道里面有哪些暗坑的人。它不是什么官方文档的翻译,而是我对RcInput从设计到落地的完整复盘,包括综合表单场景下的联动与校验、自定义样式场景下的状态拆分与主题适配,以及半年里最典型的几个Bug现场。
1. 为什么项目里需要一个RcInput,而不是直接写TextInput
1.1 需求背景:从"能用就行"到"输入体验统一"
很多团队在起步阶段对输入框的态度都是"能用就行"。我们项目也一样,最早的登录页、注册页、个人资料页、发帖页、后台搜索框,每个页面都是在需要的地方裸写一个TextInput,样式基本靠复制粘贴。等到页面多了,问题就慢慢浮出来了:有的页面圆角是8,有的是12;有的清除按钮在左边,有的在右边;有的输入框聚焦后边框会变蓝,有的压根没有聚焦反馈。
真正让我下定决心做统一封装,是一次设计走查。设计同学拿着规范稿过来问:这些输入框的边框、占位符颜色、错误提示样式,为什么每个页面都不一样?我当时没法回答,因为代码里TextInput的样式本来就是各写各的。也就是从那时候开始,RcInput正式立项,目标很明确:收敛输入框的样式、行为和交互,让业务侧不再关心"输入框长什么样",只关心"这个输入框应该输入什么"。
1.2 半年磨一剑的三阶段路线
立项容易,做起来才知道这半年是怎么过来的。整个周期我们大概分成了三个阶段:
| 阶段 | 时间 | 核心任务 | 主要产出 |
|---|---|---|---|
| v0.1 能用 | 第1个月 | 搭建组件骨架,属性对齐TextInput常用能力 | 支持占位符、清除按钮、前后缀、基础事件 |
| v0.2 好用 | 第2-3个月 | 全业务页面替换,暴露真实场景问题 | 补齐校验状态、焦点管理、键盘避让、主题适配 |
| v1.0 可靠 | 第4-6个月 | 性能优化、边界验证、多端适配 | 稳定支撑全项目综合表单与自定义样式场景 |
第一个月其实很顺利,因为只做"能用",相当于把TextInput包了一层壳,属性和事件全部透传,几乎没什么难度。但从第二个月开始,当RcInput真的被丢进各种真实业务页面时,问题才接踵而来。后面章节里提到的绝大多数坑,都是在这个阶段被业务同学一个一个踢回来的。
1.3 RcInput的边界定位
做组件最怕什么都想管。我们一开始也曾争论过,是不是要顺手把表单校验、提交逻辑也做进RcInput里,做成一个"大而全"的东西。但最后我们一致决定:RcInput只负责"输入"这件事,它不替代业务侧存储数据,也不帮你定义校验规则,它只提供三样东西:稳定统一的输入行为、清晰可控的样式状态、灵活易扩展的插槽。
这个边界很重要。因为一旦RcInput开始内置业务规则,它就会变得难复用、难维护。比如有的页面要求密码校验规则是长度6-20位,有的页面要求必须包含数字和字母,如果这些规则写死在组件里,那RcInput就不再是通用组件,而是某个业务的私有组件。把边界收敛在"输入模块"这一层,后面接表单、接校验、接主题都只是组合问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. RcInput的设计骨架:接口、结构与数据流
2.1 对外接口设计:属性区、事件区与工具区
做组件封装,接口设计是最见功底的部分。RcInput的对外接口,我大致分成三个区:属性区、事件区、工具区。
属性区负责控制组件的展示形态和输入行为,包括value(当前值)、type(输入类型,比如文本、密码、数字)、placeholder(占位符)、maxLength(最大长度)、readOnly(只读)、disabled(禁用)、clearBtn(是否显示清除按钮)、prefix(前置插槽)、suffix(后置插槽)、error(是否处于错误态)、showCounter(是否显示字数统计)等。
事件区负责把输入行为上报给外部,包括onInput(输入事件)、onFocus(聚焦)、onBlur(失焦)、onSubmit(提交搜索或回车)、onClear(点击清除按钮)等。
工具区则提供一些脱离渲染层的能力,比如focusController(焦点控制)和validate(触发校验)。接口设计遵循一个最简单的原则:外部通过属性控制组件,组件通过事件把结果告诉外部,数据流向永远是单向的。这样不管接入的是表单页面还是独立搜索框,心智负担都很小。
