#跟着若城学鸿蒙# HarmonyOS NEXT学习之StepperItem组件在表单验证中的应用
·
一、场景介绍
在实际开发中,表单验证是一个常见的需求场景。本文将介绍如何使用StepperItem组件来构建一个分步骤的表单验证流程,包括个人信息填写、联系方式验证和账户设置三个步骤。
二、功能实现
1. 页面结构设计
@Entry
@Component
struct FormValidationExample {
@State currentStep: number = 0
@State formData: {[key: string]: string} = {
name: '',
age: '',
phone: '',
email: '',
username: '',
password: ''
}
@State errors: {[key: string]: string} = {}
build() {
Column() {
// 步骤指示器
Stepper() {
StepperItem() {
Text('个人信息')
.fontSize(16)
.fontWeight(FontWeight.Bold)
}.status(this.currentStep > 0 ? ItemState.COMPLETED :
this.currentStep === 0 ? ItemState.CURRENT : ItemState.WAITING)
StepperItem() {
Text('联系方式')
.fontSize(16)
.fontWeight(FontWeight.Bold)
}.status(this.currentStep > 1 ? ItemState.COMPLETED :
this.currentStep === 1 ? ItemState.CURRENT : ItemState.WAITING)
StepperItem() {
Text('账户设置')
.fontSize(16)
.fontWeight(FontWeight.Bold)
}.status(this.currentStep === 2 ? ItemState.CURRENT : ItemState.WAITING)
}.margin({ top: 20, bottom: 40 })
// 表单内容区域
this.renderFormContent()
// 操作按钮
Row() {
if (this.currentStep > 0) {
Button('上一步')
.onClick(() => this.previousStep())
.margin({ right: 20 })
}
Button(this.currentStep === 2 ? '提交' : '下一步')
.onClick(() => this.nextStep())
}.margin({ top: 40 })
}.padding(20)
}
@Builder
renderFormContent() {
Column() {
if (this.currentStep === 0) {
this.renderPersonalInfo()
} else if (this.currentStep === 1) {
this.renderContactInfo()
} else {
this.renderAccountInfo()
}
}
}
@Builder
renderPersonalInfo() {
Column() {
TextInput({ placeholder: '请输入姓名' })
.onChange((value: string) => {
this.formData.name = value
this.validateField('name', value)
})
if (this.errors.name) {
Text(this.errors.name)
.fontSize(12)
.fontColor(Color.Red)
.margin({ top: 4 })
}
TextInput({ placeholder: '请输入年龄' })
.type(InputType.Number)
.margin({ top: 20 })
.onChange((value: string) => {
this.formData.age = value
this.validateField('age', value)
})
if (this.errors.age) {
Text(this.errors.age)
.fontSize(12)
.fontColor(Color.Red)
.margin({ top: 4 })
}
}.width('100%')
}
@Builder
renderContactInfo() {
Column() {
TextInput({ placeholder: '请输入手机号' })
.type(InputType.Number)
.onChange((value: string) => {
this.formData.phone = value
this.validateField('phone', value)
})
if (this.errors.phone) {
Text(this.errors.phone)
.fontSize(12)
.fontColor(Color.Red)
.margin({ top: 4 })
}
TextInput({ placeholder: '请输入邮箱' })
.margin({ top: 20 })
.onChange((value: string) => {
this.formData.email = value
this.validateField('email', value)
})
if (this.errors.email) {
Text(this.errors.email)
.fontSize(12)
.fontColor(Color.Red)
.margin({ top: 4 })
}
}.width('100%')
}
@Builder
renderAccountInfo() {
Column() {
TextInput({ placeholder: '请输入用户名' })
.onChange((value: string) => {
this.formData.username = value
this.validateField('username', value)
})
if (this.errors.username) {
Text(this.errors.username)
.fontSize(12)
.fontColor(Color.Red)
.margin({ top: 4 })
}
TextInput({ placeholder: '请输入密码' })
.type(InputType.Password)
.margin({ top: 20 })
.onChange((value: string) => {
this.formData.password = value
this.validateField('password', value)
})
if (this.errors.password) {
Text(this.errors.password)
.fontSize(12)
.fontColor(Color.Red)
.margin({ top: 4 })
}
}.width('100%')
}
validateField(field: string, value: string) {
switch (field) {
case 'name':
if (!value) {
this.errors.name = '姓名不能为空'
} else if (value.length < 2) {
this.errors.name = '姓名长度不能少于2个字符'
} else {
delete this.errors.name
}
break
case 'age':
if (!value) {
this.errors.age = '年龄不能为空'
} else if (parseInt(value) < 18 || parseInt(value) > 100) {
this.errors.age = '年龄必须在18-100岁之间'
} else {
delete this.errors.age
}
break
case 'phone':
if (!value) {
this.errors.phone = '手机号不能为空'
} else if (!/^1\d{10}$/.test(value)) {
this.errors.phone = '请输入正确的手机号'
} else {
delete this.errors.phone
}
break
case 'email':
if (!value) {
this.errors.email = '邮箱不能为空'
} else if (!/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(value)) {
this.errors.email = '请输入正确的邮箱地址'
} else {
delete this.errors.email
}
break
case 'username':
if (!value) {
this.errors.username = '用户名不能为空'
} else if (value.length < 4) {
this.errors.username = '用户名长度不能少于4个字符'
} else {
delete this.errors.username
}
break
case 'password':
if (!value) {
this.errors.password = '密码不能为空'
} else if (value.length < 6) {
this.errors.password = '密码长度不能少于6个字符'
} else {
delete this.errors.password
}
break
}
}
validateCurrentStep(): boolean {
const fieldsToValidate = {
0: ['name', 'age'],
1: ['phone', 'email'],
2: ['username', 'password']
}
const currentFields = fieldsToValidate[this.currentStep]
currentFields.forEach(field => {
this.validateField(field, this.formData[field])
})
return !currentFields.some(field => this.errors[field])
}
nextStep() {
if (this.validateCurrentStep()) {
if (this.currentStep === 2) {
this.submitForm()
} else {
this.currentStep++
}
}
}
previousStep() {
if (this.currentStep > 0) {
this.currentStep--
}
}
submitForm() {
// 在实际应用中,这里会发送请求到服务器
AlertDialog.show({
title: '提交成功',
message: '表单数据已成功提交',
confirm: {
value: '确定',
action: () => {
// 重置表单
this.currentStep = 0
this.formData = {
name: '',
age: '',
phone: '',
email: '',
username: '',
password: ''
}
this.errors = {}
}
}
})
}
}
三、实现要点
1. 状态管理
- 使用
@State
装饰器管理表单数据和当前步骤 - 通过
errors
对象存储表单验证错误信息 - 实现了表单数据的双向绑定
2. 表单验证
- 为每个字段实现了实时验证
- 在进入下一步之前进行当前步骤的表单验证
- 提供了清晰的错误提示
3. 步骤控制
- 实现了前进、后退功能
- 根据当前步骤动态显示不同的表单内容
- 最后一步完成后显示提交成功提示
四、总结
本文通过使用HarmonyOS的StepperItem组件,实现了一个分步骤的表单验证流程。通过状态管理、表单验证和步骤控制等功能,展示了如何构建一个结构清晰、用户体验良好的表单验证系统。这种分步骤的表单设计不仅提高了用户填写表单的效率,还增强了表单验证的准确性和易用性。
更多推荐
所有评论(0)