Async-Validator——表单验证的艺术

时间:2024-10-06 17:25:11

在现代 web 应用开发中,表单验证是一个不可或缺的部分。它确保了用户输入的数据符合预期的格式和规则,从而提高了数据的质量和用户体验。async-validator 是一个强大的 JavaScript 库,它专门用于异步表单验证,被广泛应用于主流 UI 组件库如 Ant Design 和 Element 中。本文将介绍如何使用 async-validator 来实现表单验证,并提供一个实际的案例分析。

什么是 async-validator?

async-validator 是一个基于 JavaScript 的表单验证库,它支持异步验证规则和自定义验证规则。这意味着你可以在验证过程中执行异步操作,比如从服务器检查用户名是否已存在。

为什么选择 async-validator?

  • 异步支持:能够在验证过程中执行异步操作。
  • 自定义验证规则:支持创建自定义验证规则,满足特定的验证需求。
  • 主流 UI 组件库支持:Ant Design 和 Element 等 UI 组件库的表单验证都是基于 async-validator

如何使用 async-validator?

使用步骤:

  1. 安装并在项目中导入 async-validator
  2. 创建验证规则 rules
  3. 创建表单验证实例,将验证规则传递给构造函数,产生实例
  4. 调用实例方法 validate 对数据进行验证
    • 第一个参数:需要验证的数据
    • 第二个参数:回调函数,回调函数有两个参数 errors, fields
      • errors:如果验证成功,返回 null,验证错误,返回数组
      • fields:需要验证的字段,属性值错误数组

安装

首先,你需要安装 async-validator

npm i async-validator

创建验证规则

创建一个包含验证规则的对象,每个字段的规则可以是一个对象,也可以是包含多个规则的对象数组。

创建表单验证实例

使用 async-validator 创建一个验证实例,将定义好的规则对象传递给它。

调用实例方法 validate 对数据进行验证

validate 方法接受两个参数:需要验证的数据和一个回调函数。回调函数有两个参数:errorsfieldserrors 是一个数组,包含所有验证错误;fields 是一个对象,包含每个字段的验证错误数组。

实例代码

以下是使用 async-validator 的示例代码:

// 1️⃣ 引入 async-validator,async-validator 提供了一个构造函数
import Schema from 'async-validator'

Page({
  // 2️⃣定义需要验证的数据
  data: {
    name: '你好'
  },

  // 验证数据
  onValidate() {
    // 3️⃣创建表单验证规则
    const rules = {
      // key 建议和 需要验证的数据字段名字保持一致
      name: [
        // required 是否是必填项
        { required: true, message: 'name 不能为空' },

        // type 数据的类型
        // message 如果验证失败,提示的错误内容
        { type: 'string', message: 'name 不是字符串' },

        // min 最少位数,max 最大位数
        { min: 2, max: 5, message: '名字最少 2 个字,最多 5 个字' }

        // 正则表达式
        // { pattern: '', message: '' }

        // 自定义验证规则
        // { validator: () => {} }
      ]
    }

    // 4️⃣创建表单验证实例
    // 在创建实例时需要传入验证规则
    const validator = new Schema(rules)

    // 5️⃣ 调用 validate 实例方法对数据进行验证
    // validate 方法接收一个对象作为参数,对象是需要验证的数据
    // 注意:validate 方法只会验证和验证规则同名的属性
    validator.validate(this.data, (errors, fields) => {
   // 如果验证失败,errors 是所有错误的数组
      // 如果验证成功,errors 是 null
      console.log(errors)

      // fields 是需要验证的属性,属性值是数组,数组中包含错误信息
      console.log(fields)

      if (errors) {
        console.log('验证没有通过')
        console.log(errors)
        return
      }

      console.log('验证通过')
    })
  }
})

新增收货地址表单验证

在点击新增收货地址的时候,我们需要对用户输入的值进行验证。以下是具体的实现步骤和代码:

验证需求

  1. 收货人不能为空,且不能输入特殊字符。
  2. 手机号不能为空,且输入的手机号必须合法。
  3. 省市区不能为空。
  4. 详细地址不能为空。

正则表达式

const nameRegExp = '^[a-zA-Z\\d\\u4e00-\\u9fa5]+$';
const phoneReg = '^1(?:3\\d|4[4-9]|5[0-35-9]|6[67]|7[0-8]|8\\d|9\\d)\\d{8}$';

实现代码

import Schema from 'async-validator'

Page({

  // coding....

    // 保存收货地址
  async saveAddrssForm() {
    // 组织参数 (完整地址、是否设置为默认地址)

    const {
      provinceName,
      cityName,
      districtName,
      address,
      isDefault
    } = this.data

    // 最终需要发送的请求参数
    const params = {
      ...this.data,
      fullAddress: provinceName + cityName + districtName + address,
      isDefault: isDefault ? 1 : 0
    }

    // 调用方法对最终的请求参数进行验证
    const { valid } = await this.validateAddress(params)

    // 如果验证没有通过,不继续执行后续的逻辑
    if (!valid) return
    
    console.log(params)
  },

  // 验证新增收货地址请求参数
  // 形参 params 是需要验证的数据
  validateAddress(params) {
    // 验证收货人,是否只包含大小写字母、数字和中文字符
    const nameRegExp = '^[a-zA-Z\\d\\u4e00-\\u9fa5]+$'

    // 验证手机号
    const phoneReg = '^1(?:3\\d|4[4-9]|5[0-35-9]|6[67]|7[0-8]|8\\d|9\\d)\\d{8}$'

    // 创建验证规则,验证规则是一个对象
    // 每一项是一个验证规则,验证规则属性需要和验证的数据进行同名
    const rules = {
      name: [
        { required: true, message: '请输入收货人姓名' },
        { pattern: nameRegExp, message: '收货人姓名不合法' }
      ],
      phone: [
        { required: true, message: '请输入收货人手机号' },
        { pattern: phoneReg, message: '手机号不合法' }
      ],
      provinceName: { required: true, message: '请选择收货人所在地区' },
      address: { required: true, message: '请输入详细地址' }
    }

    // 创建验证实例,并传入验证规则
    const validator = new Schema(rules)

    // 调用实例方法对数据进行验证
    // 注意:我们希望将验证结果通过 Promsie 的形式返回给函数的调用者
    return new Promise((resolve) => {
      validator.validate(params, (errors, fields) => {
        if (errors) {
          // 如果验证失败,需要给用户进行提示
          wx.toast({
            title: errors[0].message
          })

          resolve({ valid: false })
        } else {
          resolve({ valid: true })
        }
      })
    })
  },


  // coding...
})

通过上述步骤和代码,你可以轻松地实现一个功能完备的表单验证逻辑,确保用户输入的数据符合业务规则。