#跟着若城学鸿蒙# HarmonyOS NEXT学习之SpanStepper案例四:多步骤表单验证系统
·
一、案例介绍
本案例将展示如何使用SpanStepper组件实现一个多步骤表单验证系统,包括表单数据验证、错误提示和状态管理等功能。
二、代码实现
@Entry
@Component
struct FormValidationExample {
@State currentStep: number = 0
@State formData: {
username: string,
password: string,
email: string,
phone: string,
address: string,
company: string
} = {
username: '',
password: '',
email: '',
phone: '',
address: '',
company: ''
}
@State errors: {
username: string,
password: string,
email: string,
phone: string,
address: string,
company: string
} = {
username: '',
password: '',
email: '',
phone: '',
address: '',
company: ''
}
// 验证用户名
validateUsername(username: string): boolean {
if (username.length < 3) {
this.errors.username = '用户名至少需要3个字符'
return false
}
this.errors.username = ''
return true
}
// 验证密码
validatePassword(password: string): boolean {
const regex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/
if (!regex.test(password)) {
this.errors.password = '密码至少8位,包含字母和数字'
return false
}
this.errors.password = ''
return true
}
// 验证邮箱
validateEmail(email: string): boolean {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (!regex.test(email)) {
this.errors.email = '请输入有效的邮箱地址'
return false
}
this.errors.email = ''
return true
}
// 验证手机号
validatePhone(phone: string): boolean {
const regex = /^1[3-9]\d{9}$/
if (!regex.test(phone)) {
this.errors.phone = '请输入有效的手机号'
return false
}
this.errors.phone = ''
return true
}
// 验证当前步骤
validateCurrentStep(): boolean {
if (this.currentStep === 0) {
return this.validateUsername(this.formData.username) &&
this.validatePassword(this.formData.password)
} else if (this.currentStep === 1) {
return this.validateEmail(this.formData.email) &&
this.validatePhone(this.formData.phone)
}
return true
}
build() {
Column() {
// 步骤指示器
SpanStepper() {
StepperItem() {
Column() {
Text('基本信息').fontSize(16).fontWeight(FontWeight.Bold)
Text('账号和密码').fontSize(14).opacity(0.6)
}
}
.status(this.currentStep === 0 ? ItemState.CURRENT :
this.currentStep > 0 ? ItemState.COMPLETED : ItemState.WAITING)
StepperItem() {
Column() {
Text('详细信息').fontSize(16).fontWeight(FontWeight.Bold)
Text('联系方式').fontSize(14).opacity(0.6)
}
}
.status(this.currentStep === 1 ? ItemState.CURRENT :
this.currentStep > 1 ? ItemState.COMPLETED : ItemState.WAITING)
StepperItem() {
Column() {
Text('确认提交').fontSize(16).fontWeight(FontWeight.Bold)
Text('信息确认').fontSize(14).opacity(0.6)
}
}
.status(this.currentStep === 2 ? ItemState.CURRENT : ItemState.WAITING)
}
.width('100%')
.padding(16)
// 表单内容
Column() {
if (this.currentStep === 0) {
// 基本信息表单
TextInput({ placeholder: '请输入用户名' })
.width('100%')
.height(48)
.margin({ top: 16 })
.onChange((value: string) => {
this.formData.username = value
this.validateUsername(value)
})
if (this.errors.username) {
Text(this.errors.username)
.fontSize(12)
.fontColor(Color.Red)
.margin({ top: 4 })
}
TextInput({ placeholder: '请输入密码', type: InputType.Password })
.width('100%')
.height(48)
.margin({ top: 16 })
.onChange((value: string) => {
this.formData.password = value
this.validatePassword(value)
})
if (this.errors.password) {
Text(this.errors.password)
.fontSize(12)
.fontColor(Color.Red)
.margin({ top: 4 })
}
} else if (this.currentStep === 1) {
// 详细信息表单
TextInput({ placeholder: '请输入邮箱' })
.width('100%')
.height(48)
.margin({ top: 16 })
.onChange((value: string) => {
this.formData.email = value
this.validateEmail(value)
})
if (this.errors.email) {
Text(this.errors.email)
.fontSize(12)
.fontColor(Color.Red)
.margin({ top: 4 })
}
TextInput({ placeholder: '请输入手机号' })
.width('100%')
.height(48)
.margin({ top: 16 })
.onChange((value: string) => {
this.formData.phone = value
this.validatePhone(value)
})
if (this.errors.phone) {
Text(this.errors.phone)
.fontSize(12)
.fontColor(Color.Red)
.margin({ top: 4 })
}
TextInput({ placeholder: '请输入公司名称' })
.width('100%')
.height(48)
.margin({ top: 16 })
.onChange((value: string) => {
this.formData.company = value
})
TextArea({ placeholder: '请输入详细地址' })
.width('100%')
.height(80)
.margin({ top: 16 })
.onChange((value: string) => {
this.formData.address = value
})
} else {
// 信息确认
Column() {
Text('信息确认').fontSize(20).fontWeight(FontWeight.Bold)
Text(`用户名:${this.formData.username}`)
.fontSize(16)
.margin({ top: 16 })
Text(`邮箱:${this.formData.email}`)
.fontSize(14)
.margin({ top: 8 })
Text(`手机号:${this.formData.phone}`)
.fontSize(14)
.margin({ top: 8 })
Text(`公司:${this.formData.company}`)
.fontSize(14)
.margin({ top: 8 })
Text(`地址:${this.formData.address}`)
.fontSize(14)
.margin({ top: 8 })
}
.width('100%')
.padding(16)
}
}.width('100%').padding({ left: 16, right: 16 })
// 操作按钮
Row() {
Button('上一步')
.enabled(this.currentStep > 0)
.opacity(this.currentStep > 0 ? 1 : 0.5)
.onClick(() => {
if (this.currentStep > 0) {
this.currentStep--
}
})
Button(this.currentStep === 2 ? '提交' : '下一步')
.enabled(this.validateCurrentStep())
.onClick(() => {
if (this.currentStep < 2) {
this.currentStep++
} else {
// 在实际应用中,这里可以处理表单提交逻辑
console.info('表单提交成功')
}
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
.padding(16)
.margin({ top: 20 })
}
}
}
三、代码解析
1. 状态定义
@State formData: { // 表单数据对象
username: string,
password: string,
email: string,
phone: string,
address: string,
company: string
}
@State errors: { // 错误信息对象
username: string,
password: string,
email: string,
phone: string,
address: string,
company: string
}
- 使用
@State
装饰器定义表单数据和错误信息 - 分别存储每个字段的值和对应的错误提示
2. 表单验证
validateUsername(username: string): boolean {
if (username.length < 3) {
this.errors.username = '用户名至少需要3个字符'
return false
}
this.errors.username = ''
return true
}
validateCurrentStep(): boolean {
if (this.currentStep === 0) {
return this.validateUsername(this.formData.username) &&
this.validatePassword(this.formData.password)
}
// ...
}
- 为每个字段实现单独的验证方法
- 使用正则表达式进行格式验证
- 实现步骤级别的验证方法
3. 错误提示
TextInput({ placeholder: '请输入用户名' })
.onChange((value: string) => {
this.formData.username = value
this.validateUsername(value)
})
if (this.errors.username) {
Text(this.errors.username)
.fontSize(12)
.fontColor(Color.Red)
}
- 在输入框下方显示错误提示
- 使用红色文字突出显示错误信息
- 实时验证并更新错误状态
4. 按钮状态控制
Button(this.currentStep === 2 ? '提交' : '下一步')
.enabled(this.validateCurrentStep())
.onClick(() => {
if (this.currentStep < 2) {
this.currentStep++
} else {
console.info('表单提交成功')
}
})
- 根据验证结果控制按钮状态
- 只有当前步骤验证通过才能继续
- 最后一步显示提交按钮
四
通过本案例,我们学习了:
- SpanStepper组件在表单验证中的应用
- 如何实现表单数据的验证和错误提示
- 使用正则表达式进行数据格式验证
- 表单状态的管理和控制
这些知识点将帮助你在实际项目中实现更严谨的表单验证功能。
更多推荐
所有评论(0)