前言
在前端开发中,表单验证是很常见的功能,这边文章就来讲一下react入门实现复杂表单的功能,以及表单验证功能的实现
复杂表单页面的实现
实现一个表单页面,包含输入框,单选框和下拉框,点击提交能够拿取输入的数据
1.首先定义我们的非受限组件Hello,并在state中定义我们需要用到的变量:
class Hello extends React.Component {
state = {
name: '',
sex: '2',
select: 'A',
select2: '',
select3: '',
text: 'hello world'
}
}
2.然后在组件中来写我们的render()方法:
先把上面定义的state进行结构,定义arr1数组用来存放下拉框需要的数据,arr2是一个数组对象,里面也是我们实际开放中最常用的格式,用来渲染另一个下拉框
然后在return中开始写页面的内容
render() {
let { name, sex, select, select2, select3, text } = this.state
let arr1 = ['D', 'E', 'F', 'G', 'H']
let arr2 = [{id: 1, color: 'red'}, {id: 2, color: 'green'}, {id: 3, color: 'blue'}]
return <div>
<form>
<label>姓名:<input type="text" name="name" defaultValue={name} onChange={this.handleChange} /></label><br/>
<label>性别:
<input type="radio" name='sex' value="1"
defaultChecked={sex === '1' ? true : false}
onChange={this.handleChange}/>男
<input type="radio" name='sex' value="2"
defaultChecked={sex === '2' ? true : false}
onChange={this.handleChange}/>女
</label><br/>
<label>写死的选项:
<select name="select" defaultValue={select} onChange={this.handleChange}>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
</label><br/>
<label>循环遍历出来的选项:
<select name="select2" defaultValue={select2} onChange={this.handleChange}>
{
arr1.map((item, index) =>
<option key={index} value={item}>{item}</option>
)
}
</select>
</label><br/>
<label>数组中是对象的数据循环遍历处理:
<select name="select3" defaultValue={select3} onChange={this.handleChange}>
{
arr2.map(item =>
<option key={item.id} value={item.id}>{item.color}</option>
)
}
</select>
</label><br/>
<label>备注信息:
<textarea name="text" defaultValue={text} onChange={this.handleChange}></textarea>
</label>
</form>
<button onClick={this.handleSubmit}>点击提交</button>
</div>
}
在上面的select中,我们使用循环讲arr1中的内容展现出来,第二个select中是对数组中对象的数据循环遍历的处理方式,注意观察他们的写法不同
3.给每个输入框添加onChange事件,给button按钮添加onClick事件提交表单
下面来写一下这个两个函数:
handleChange是输入框值改变就触发的时间,我们通过给每个元素绑定name值,然后封装起来,注意这里this.setState里面是[name],数组的形式,e.target.value拿到输入的值并赋值
handleSubmit是将表单的值提交,然后打印出来
handleChange = (e) => {
let name = e.target.name
this.setState({[name]: e.target.value})
}
handleSubmit = () => {
console.log(this.state)
}
效果展示:
表单验证方法
下面来讲在表单中加入表单验证如何写,这里就不用上面的那个表单,写一个新的表单包含昵称,密码,手机号,主要来看看怎么实现表单验证:
再输入框后面加上span标签,用来展示错误提示信息,里面绑定对应的错误信息如{nameError}
return <div>
<form>
<label>姓名:<input type="text" name="name"
defaultValue={name} onChange={this.nameChange} />
<span className='danger'>{nameError}</span>
</label><br/>
<label>密码:<input type="password" name="password"
defaultValue={password} onChange={this.passChange} />
<span className='danger'>{passwordError}</span>
</label><br/>
<label>性别:
<input type="radio" name="sex" value="1"
checked={sex === '1' ? true : false} onChange={this.handleClick} />
<input type="radio" name="sex" value="2"
checked={sex === '2' ? true : false} onChange={this.handleClick} />
</label><br/>
<label>手机号:<input type="text" name="phone"
defaultValue={phone} onChange={this.phoneChange} />
<span className='danger'>{phoneError}</span>
</label><br/>
<label>选择城市:
<select name="select" defaultValue={select} onChange={this.handleClick}>
{
arr.map(item => {
return <option key={item.id} value={item.id}>{item.city}</option>
})
}
</select>
</label><br/>
</form>
<button onClick={this.handleSubmit}>点击提交</button>
</div>
然后定义表单验证的函数:
将组件传过来的值进行判断,给出对应的error展示
// 姓名校验处理
nameChange = (e) => {
let rule = /^[a-zA-Z0-9]{4,10}$/
let value = e.target.value
let error = ''
if(!value) {
error = '请输入昵称'
} else if (!rule.test(value)) {
error = '请输入4-10位昵称'
} else {
error = ''
}
this.setState({
name: value,
nameError: error
})
}
passChange = (e) => {
let rule = /^\S*(?=\S{6,12})(?=\S*\d)(?=\S*[A-Z])(?=\S*[a-z])(?=\S*[!@#$%^&*? ])\S*$/
let value = e.target.value
let error = ''
if(!value) {
error = '请输入密码'
} else if (!rule.test(value)) {
error = '请输入6-12需要包含大小写字母和数字以及特殊符号'
} else {
error = ''
}
this.setState({
password: value,
passwordError: error
})
}
phoneChange = (e) => {
let rule = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/
let value = e.target.value
let error = ''
if(!value) {
error = '请输入手机号'
} else if (!rule.test(value)) {
error = '请输入格式正确的手机号'
} else {
error = ''
}
this.setState({
phone: value,
phoneError: error
})
}
来看效果:
这样我们便实现了表单校验,但是如果表单内容比较多,那么验证的代码就要写很多,对于这一块如何去优化呢?继续往下
表单验证方法的优化
对于上面表单验证的方法,很明显有很多重复的地方,那么就可以对其进行封装
将rule的内容写成传参的形式
在函数中使用new RegExp描述正则,e.target.getAttribute('rule')取到rule的值
使用name+‘Error’拼接名字进行赋值
// 校验方法封装
handleChange(e, info1, info2){
// console.log(e.target);
let { name, value } = e.target
let rule = new RegExp(e.target.getAttribute('rule'))
let error = ''
if(!value) {
error = info1
} else if (!rule.test(value)) {
error = info2
} else {
error = ''
}
this.setState({
[name]: value,
[name + 'Error']: error
})
}
<label>姓名:<input type="text" name="name"
rule="^[a-zA-Z0-9]{4,10}"
defaultValue={name} onChange={(e) => this.handleChange(e, '请输入昵称','请输入4-10位昵称')} />
<span className='danger'>{nameError}</span>
</label><br/>
<label>密码:<input type="password" name="password"
rule="^\S*(?=\S{6,12})(?=\S*\d)(?=\S*[A-Z])(?=\S*[a-z])(?=\S*[!@#$%^&*? ])\S*$"
defaultValue={password} onChange={(e) => this.handleChange(e, '请输入密码','请输入6-12需要包含大小写字母和数字以及特殊符号')} />
<span className='danger'>{passwordError}</span>
</label><br/>
<label>性别:
<input type="radio" name="sex" value="1"
checked={sex === '1' ? true : false} onChange={this.handleClick} />
<input type="radio" name="sex" value="2"
checked={sex === '2' ? true : false} onChange={this.handleClick} />
</label><br/>
<label>手机号:<input type="text" name="phone"
rule="^(?:(?:\+|00)86)?1[3-9]\d{9}$"
defaultValue={phone} onChange={(e) => this.handleChange(e, '请输入手机号','请输入格式正确的手机号')} />
<span className='danger'>{phoneError}</span>
</label><br/>
这样写起来是不是代码量少了很多呢,实现的效果是完全一样的
如果对你有帮助,点赞支持一下呀,关注我后续会带来更多优质内容~