表单验证 —— 告别杂乱无章

401 阅读2分钟

许多新手在写表单验证时,会写很多冗余代码。尤其出现多个input和多种验证格式时,每次onchange的时候都要判断一下,最后函数写的老长... ...

当然现在有很多表单验证的库可以使用,但是在项目开发时,大多数验证是个性化的,自己写起来是更方便的啦~

现在来举个例子:

name:不为空且不超过10个字符

count:必须是整数

mobile:正则格式

work:不能为空

以上是我们的表单项。那我们需要做哪些事情呢?

1、写好各验证方法

2、写好rulers的格式(数组形式,包含方法与message)

3、表单提交时显示错误内容(一般提示第一个错误即可)

验证方法

  // 不为空
  notEmpty = (val) => {
    return !!val.trim()    // 字符串转bool用!!
  }
  
  // 不超过number个字符
  isLength = (val, number) => {
    return val.trim().length < number
  }
  
  // 必须是整数
  isInteger = (val) => {
    return /^\+?[1-9][0-9]*$/.test(val)
  }
  
  // 电话格式
  isMobile = (val) => {
    return /^1[3456789]\d{9}$/.test(val)
  }
  

rulers规则

const rulers = {
  name: [
    {
      func: this.notEmpty(this.state.name),
      message: '名称不能为空'
    },
    {
      func: this.isLength(this.state.name, 10),
      message: '名称不能超过10个字'
    }
  ],
  count: [
    {
      func: this.isInteger(this.state.count),
      message: '接待量必须是整数'
    }
  ],
  mobile: [
    {
      func: this.isMobile(this.state.mobile),
      message: '请填写正确的手机号码'
    }
  ],
  work: [
    {
      func: this.notEmpty(this.state.work),
      message: '岗位名称不能为空'
    }
  ]
}

表单提交时显示错误内容

// 这部分的处理方法有很多种,能遍历每一个表单项的规则即可
const arr = ['name', 'count', 'mobile', 'work']
for (let i = 0; i < arr.length; i++) {
  rulers[arr[i]].forEach(rule => {
    if (!rule.func) {
      alert(rule.message)
    }
  })
}

完整代码

这是个demo, 写项目时注意验证函数和规则要分开,另写一个文件import进来,可配置更灵活

'use strict';

class Vail extends React.Component {

  state = {
    name: '',
    count: '',
    mobile: '',
    work: '',
  }
  
  onChange = (e, name) => {
    this.setState({
      [name]: e.target.value
    })
  }
  
  notEmpty = (val) => {
    return !!val.trim()    // 字符串转bool用!!
  }

  isLength = (val, number) => {
    return val.trim().length < number
  }

  isInteger = (val) => {
    return /^\+?[1-9][0-9]*$/.test(val)
  }

  isMobile = (val) => {
    return /^1[3456789]\d{9}$/.test(val)
  }
  
  isCheck() {
    const rulers = {
      name: [
        {
          func: this.notEmpty(this.state.name),
          message: '名称不能为空'
        },
        {
          func: this.isLength(this.state.name, 10),
          message: '名称不能超过10个字'
        }
      ],
      count: [
        {
          func: this.isInteger(this.state.count),
          message: '接待量必须是整数'
        }
      ],
      mobile: [
        {
          func: this.isMobile(this.state.mobile),
          message: '请填写正确的手机号码'
        }
      ],
      work: [
        {
          func: this.notEmpty(this.state.work),
          message: '岗位名称不能为空'
        }
      ]
    }
    const arr = ['name', 'count', 'mobile', 'work']
    let flag = false
    for (let i = 0; i < arr.length; i++) {
      rulers[arr[i]].forEach(rule => {
        if (!rule.func) {
          // 这里写错误情况,有的是弹窗,有的是控制错误信息的显示与隐藏
          alert(rule.message)
          flag = true
        }
      })
      if (flag) return false
    }
    return true
  }
  
  onSubmit = () => {
    if(this.isCheck()) {
      alert('没有错误')
    }
  }
  
  render() {
    return (
      <div style={{ width: '500px', margin: '0 auto' }}>
        <label>
          name:
          <input onChange={(e) => this.onChange(e, 'name')} />
        </label>
        <br />
        <br />
        <label>
          count:
          <input onChange={(e) => this.onChange(e, 'count')} />
        </label>
        <br />
        <br />
        <label>
          mobile:
          <input onChange={(e) => this.onChange(e, 'mobile')} />
        </label>
        <br />
        <br />
        <label>
          work:
          <input onChange={(e) => this.onChange(e, 'work')} />
        </label>
        <br />
        <br />
        <button onClick={this.onSubmit}>submit</button>
      </div>
    )
  }
}

const domContainer = document.querySelector('#form_container');
ReactDOM.render(<Vail />, domContainer);

css懒得写了。。。