杨利杰YJlio博客头图

表单输入校验与提交反馈

大家好,我是杨利杰 YJlio。

上一节整理了返回导航与页面状态。这一节我用工单标题练习表单校验:输入文字,点击按钮,遇到错误给出明确提示,符合规则则显示本地反馈。

本篇编号024,计划日期2026年10月14日。原稿已保留。补充代码属于学习示例,尚未在本机编译或设备运行;图片是概念信息图。

一、先把输入、校验和反馈连起来

本例只处理工单标题,不创建完整工单。原稿中的Ticket模型还包含分类、优先级和状态,这次不扩展这些字段,先把一个输入框的路径讲清楚。

我把步骤定为:获取当前输入,去除首尾空白,检查必填和长度,最后更新提示。没有联网请求,也没有数据库写入。

先校验,再给反馈

二、沿用原稿的标题校验规则

校验函数接收字符串,返回错误文字或undefined。undefined在这里表示这两个条件没有发现错误。

function validateTitle(title: string): string | undefined {
  const value = title.trim();
  if (value.length === 0) {
    return '请填写工单标题';
  }
  if (value.length > 80) {
    return '标题不能超过80个字符';
  }
  return undefined;
}

原稿把错误提示写为“80个字符”。代码实际上通过string.length计数,也就是UTF-16码元数量;一些emoji等字符可能占多个码元。如果业务要求按用户感知的字数限制,需另定计数规则,不能把这段代码当成精确的视觉字符计数器。

去除首尾空白后的length本例处理
0提示必填
1至80这两项校验通过
大于80提示超长

标题校验的两个条件

三、去除首尾空白,不删除中间空格

trim只去掉字符串两端的空白。全是空白的输入会变成空串,因此不能靠敲几个空格绕过必填校验;正常标题中的中间空格仍然保留。

本例校验时得到一个局部value,没有立即改写输入框的title。输入展示与后续用于提交的数据可以分别处理,但校验值和真正提交值必须采用同一规则。

校验去除首尾空白后的内容,后续提交也应使用同样处理后的值。

trim只去掉首尾空白

四、把输入、错误和本地反馈分开

我使用三个页面状态:title保存当前输入,errorMessage保存错误,feedback保存本地校验通过的反馈。输入变化时清空旧提示,避免上一轮的“通过”或“错误”继续描述已经改过的内容。

TextInput通过onChange取得变化后的文字,再写回title。这里采用V1的@Component与@State;其他模板应先核对对应SDK的状态管理方式。组件事件与状态绑定可参考OpenHarmony文本输入文档。

输入和提示分别保存

五、遇到错误,停止本次处理

点击按钮时先清空旧的通过反馈,再执行validateTitle。如果函数返回错误文字,就显示errorMessage并结束本次处理,不执行后面的通过分支。

空标题和超长标题是可预期的输入问题。提示应说明用户要改哪里,不必把这种情况写成网络故障或应用异常。

输入校验错误与服务器提交失败,是两类不同的反馈。

错误就停止本次处理

六、校验通过,只说明本地规则通过

本例通过后显示“校验通过(仅本地),标题:……”并保留输入,没有声称已生成工单编号,也没有声称服务器保存成功。

如果后续接入服务,应在实际响应后判断业务结果,并处理请求失败、重复点击和服务端校验。服务端不能省略自己的校验;客户端通过不代表服务端一定接受。

本地校验通过,不等于提交成功

七、把处理逻辑放进一个完整页面

下面将validateTitle放在页面结构体外,页面内负责输入与提示。按钮叫“校验并反馈”,与它当前真正执行的操作一致。

Index.ets学习示例:

function validateTitle(title: string): string | undefined {
  const value = title.trim();
  if (value.length === 0) {
    return '请填写工单标题';
  }
  if (value.length > 80) {
    return '标题不能超过80个字符';
  }
  return undefined;
}

@Entry
@Component
struct Index {
  @State title: string = '';
  @State errorMessage: string = '';
  @State feedback: string = '';

  private validateAndFeedback(): void {
    this.feedback = '';
    const error = validateTitle(this.title);
    this.errorMessage = error === undefined ? '' : error;
    if (error !== undefined) {
      return;
    }
    const value = this.title.trim();
    this.feedback = `校验通过(仅本地),标题:${value}`;
  }

  build() {
    Column({ space: 12 }) {
      Text('工单标题')
      TextInput({ text: this.title, placeholder: '请输入工单标题' })
        .onChange((value: string) => {
          this.title = value;
          this.errorMessage = '';
          this.feedback = '';
        })
      Text(this.errorMessage).fontColor(Color.Red)
      Button('校验并反馈').onClick(() => {
        this.validateAndFeedback()
      })
      Text(this.feedback)
    }
    .width('100%')
    .padding(16)
  }
}

不要在同一文件重复声明两份validateTitle。上面的独立函数段用于解释规则,完整页面中的同名函数是同一实现的展示。

为了练习超长输入反馈,这里没有用maxLength提前截断内容。业务界面若采用输入长度限制,仍要保留提交前校验,并核对两者的计数口径。

点击后按一个顺序处理

八、用边界输入记录真实结果

输入或操作本例预期实际结果
空串提示请填写工单标题待验证
全部为空白同样提示必填待验证
去除首尾空白后长度1显示本地通过反馈待验证
长度80本地校验通过待验证
长度81提示标题不能超过80个字符待验证
通过后修改输入清空上一轮反馈待验证
有错误后修改输入清空旧错误,再点击重新校验待验证

先使用普通中文或ASCII字符构造长度边界,再单独观察emoji等输入的length。记录实际DevEco Studio、SDK/API、设备型号和窗口尺寸,保留构建输出及操作顺序。

预期结果是检查依据,真实运行记录才是验证证据。

用边界输入记录结果

写在最后

这节我保留了原稿的两条标题规则,补齐输入变化、错误分支和本地反馈。重点是让每个提示都有明确含义:必填与超长告诉用户怎样修改;本地通过说明可以进入下一步,仍不等于业务保存成功。

下一篇学习Preferences保存简单设置,再区分页面状态与持久化数据。

参考资料

  1. OpenHarmony官方文档:文本输入组件,用于核对TextInput与onChange;实际HarmonyOS工程以对应SDK资料为准。
  2. OpenHarmony官方文档:@State装饰器,用于核对组件状态与显示更新。
  3. ECMAScript规范:字符串length属性,用于说明UTF-16码元计数口径。
  4. 本系列第024篇原稿:《表单输入校验与提交反馈》,计划日期2026-10-14。

声明:本文为个人学习笔记。代码与配图用于说明校验流程;未执行本机编译或设备实测,未接入服务器,未创建真实工单。

结束分隔线

返回顶部

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐