react入门—实现复杂表单方法的封装以及表单验证功能的实现(表单验证方法的封装优化)

前言

在前端开发中,表单验证是很常见的功能,这边文章就来讲一下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/>

这样写起来是不是代码量少了很多呢,实现的效果是完全一样的

如果对你有帮助,点赞支持一下呀,关注我后续会带来更多优质内容~
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45745641/article/details/123430659
今日推荐