HarmonyOS7 TextInput 表单:输入校验与提交最佳实践
文章目录
- 前言
- 基础绑定
- 代码实现
- 实时校验:边输入边提示
- 核心代码
- 完整示例
- 提交时统一拦截
- 代码解析
- 用 @Builder 抽一个带校验的输入框
- 实现拆解
- 常见误区(小白必踩)
- 完整可运行示例:表单校验
- 代码清单
- 写在最后
前言
登录、注册、反馈、下单——几乎所有 app 都有表单。表单最烦的不是布局,而是输入校验:手机号对不对、密码够不够长、两次密码一不一致。
这篇文章我把一个"注册表单"从头写到尾,重点讲怎么在用户输入时就做校验、怎么在提交时统一拦截。照着这套写,你的表单不会再出现"点了提交才告诉我格式错"。
基础绑定
TextInput通过text和onChange跟状态双向绑定:
代码实现
@Localphone:string=''@Localpwd:string=''build(){Column({space:12}){TextInput({placeholder:'请输入手机号',text:this.phone}).onChange((v)=>{this.phone=v}).type(InputType.PhoneNumber)// 弹出数字键盘TextInput({placeholder:'请输入密码',text:this.pwd}).onChange((v)=>{this.pwd=v}).type(InputType.Password)// 密码遮罩}.padding(16)}要点:
.type(InputType.PhoneNumber):手机号输入框弹数字键盘,体验更好。.type(InputType.Password):密码输入显示圆点遮罩。onChange里更新状态,这是表单数据收集的命脉。
实时校验:边输入边提示
不要等提交才校验。用户输入时即时判断并显示错误:
核心代码
@LocalphoneError:string=''privatevalidatePhone(v:string){if(v.length===0){this.phoneError='手机号不能为空'}elseif(!/^1[3-9]\d{9}$/.test(v)){this.phoneError='手机号格式不正确'}else{this.phoneError=''// 通过,清空错误}}// 在 onChange 里调用.onChange((v)=>{this.phone=vthis.validatePhone(v)})配合界面上的错误提示:
完整示例
if(this.phoneError){Text(this.phoneError).fontSize(12).fontColor('#FF0000')}这样用户输入的瞬间就能看到红字提示,体验远胜"提交后才报错"。
提交时统一拦截
点提交时,把所有字段再校验一遍,只有全过才发请求:
代码解析
asyncfunctionsubmit(){this.validatePhone(this.phone)if(this.phoneError||this.pwd.length<6){promptAction.showToast({message:'请检查输入'})return// 有错就拦住,不发请求}// 全部通过,提交awaitthis.doRegister(this.phone,this.pwd)}- 提交前再校验一次,防止用户绕过实时校验(比如直接点了提交)。
- 任何一项不通过就
return,不发请求。这是表单的"最后一道防线"。
用 @Builder 抽一个带校验的输入框
表单字段多,重复代码多。抽一个通用输入框组件:
实现拆解
@BuilderValidatedInput(placeholder:string,value:string,error:string,onVal:(v:string)=>void){Column(){TextInput({placeholder:placeholder,text:value}).onChange(onVal)if(error){Text(error).fontSize(12).fontColor('#FF0000')}}}// 使用:// this.ValidatedInput('手机号', this.phone, this.phoneError, v => { this.phone = v; this.validatePhone(v) })一个ValidatedInput复用到所有字段,注册、登录、反馈表单全通用。
常见误区(小白必踩)
| 误区 | 说明 |
|---|---|
| 不实时校验 | 等提交才报错,用户体验差。用户输入瞬间就该红字提示。 |
| 提交不统一拦截 | 实时校验可能被绕过(比如直接点提交),提交时再校验一次是最后防线。 |
type不设导致键盘错 | 手机号用InputType.PhoneNumber弹数字键盘,密码用Password遮罩。 |
下面这段代码可以直接复制到 DevEco Studio 里运行。建议你边读边敲,改一改文末「动手改一改」里的参数,亲眼看看效果。
完整可运行示例:表单校验
实时校验手机号格式,校验通过才允许提交。
代码清单
// TextInput 输入校验@Entry@Componentstruct Form{@Statephone:string=''@Stateerr:string=''privatecheck(v:string){if(!/^1\d{10}$/.test(v)){this.err='请输入 11 位手机号'}else{this.err=''// 通过则清空错误}}build(){Column({space:12}){TextInput({placeholder:'手机号'}).onChange((v)=>{this.phone=v;this.check(v)})if(this.err){Text(this.err).fontColor('#E53935').fontSize(12)}Button('提交').enabled(this.err===''&&this.phone.length>0)}.padding(20)}}你会看到什么:输入非手机号时下方立刻显示红色错误提示,且「提交」按钮变灰不可点;格式正确后提示消失、按钮恢复可点。
动手改一改:
- 把正则换成邮箱校验
/^\S+@\S+\.\S+$/。 - 用
TextInput({ text: $$this.phone } })双向绑定简化状态。 - 给错误提示加
transition让它平滑出现。
写在最后
表单校验的黄金法则:实时校验给即时反馈,提交时再统一拦截。两者缺一不可——实时校验管体验,提交拦截管安全。
把校验逻辑(手机号正则、密码长度)抽成独立函数,配合ValidatedInput复用,你的表单代码会清爽一大截。下次写表单,先把这些工具备好再动手。
