## 校验规则

在表单上传入`validate`属性，可为表单添加校验规则，校验规则有框架内部定义好的一些规则可以直接使用，还可以自定义校验规则，通过 method 传入。下面介绍一些常用的校验 demo。

### 必填校验，输入值相同校验

`required`校验必填，`confirmed`对比两个值是否相同。此场景适用于设置新密码。

```html
<template>
  <el-form :model="confirmForm" label-width="80px">
    <cl-form-item label="密码">
      <cl-input v-model="confirmForm.password" validate="required" type="password"></cl-input>
    </cl-form-item>
    <cl-form-item label="确认密码">
      <cl-input type="password" v-model="confirmForm.surePassword" :validate="`required|confirmed:${confirmForm.password}`"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          password: '',
          surePassword: ''
        }
      }
    }
  }
</script>
<style>
  .el-row {
    margin-bottom: 15px;
  }
</style>
<!-- validation1.vue -->
```

### 邮箱校验

`email`校验邮箱。

```html
<template>
  <el-form :model="confirmForm" label-width="80px">
    <cl-form-item label="邮箱">
      <cl-input v-model="confirmForm.email" validate="email"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          email: ''
        }
      }
    }
  }
</script>
<style>
  .el-row {
    margin-bottom: 15px;
  }
</style>
<!-- validation2.vue -->
```

### 正则表达式校验

注意输入的正则表达式不能是/^[0-9]+$/格式，我们在解析校验规则时，会通过newRegExp(args[0])的方式来生成正则表达式对象。注意:字符串格式的表达式以英文逗号,来分割参数，如果正则表达式或者提示信息中包含了英文逗号，会导致校验规则的解析错误。这种情况下，我们需要按照Object格式来编写校验表达式:validate="{regex:{exp:'^[0-9]+$',message:'校验失败，请输入数字。'}}"

```html
<template>
  <el-form :model="confirmForm">
    <cl-form-item label="数字(字符串传参)" label-width="150px">
      <cl-input v-model="confirmForm.num1" validate="regex:^[0-9]+$,校验失败"></cl-input>
    </cl-form-item>
    <cl-form-item label="数字(对象传参)" label-width="150px">
      <cl-input v-model="confirmForm.num2" :validate="{regex:{exp:'^[0-9]+$',message:'校验失败，请输入数字。'}}"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          num1: '',
          num2: ''
        }
      }
    }
  }
</script>
<style>
  .el-row {
    margin-bottom: 15px;
  }
</style>
<!-- validation3.vue -->
```

### 最大最小数值和最大最小长度

限制文本长度时使用`min`、`max`，限制数值最大最小值时使用`min_value`、`max_value`。

```html
<template>
  <el-form :model="confirmForm">
    <cl-form-item label="限制字符串长度" label-width="150px">
      <cl-input v-model="confirmForm.num1" validate="min:3|max:5"></cl-input>
    </cl-form-item>
    <cl-form-item label="限制数值大小" label-width="150px">
      <cl-input v-model="confirmForm.num2" validate="min_value:20|max_value:100"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          num1: '',
          num2: ''
        }
      }
    }
  }
</script>
<style>
  .el-row {
    margin-bottom: 15px;
  }
</style>
<!-- validation4.vue -->
```

#### 范围校验

`isAfter`日期晚于，，`isBefore`日期早于，`isStart`日期不早于，`isEnd`日期不晚于，均需要传入另一需要对比的字段 model 属性，

```html
<template>
  <el-form :model="validateRange" label-width="80px">
    <cl-form-item label="isBefore">
      <cl-date
        v-model="validateRange.isBefore"
        format="yyyy-MM-dd"
        value-format="yyyy-MM-dd"
        :validate="{'required':true,'isBefore': new Date().format('yyyy-MM-dd')}"
      />
    </cl-form-item>
    <cl-form-item label="isAfter">
      <cl-date
        v-model="validateRange.isAfter"
        format="yyyy-MM-dd hh:mm:ss"
        value-format="yyyy-MM-dd hh:mm:ss"
        :validate="{'required':true,'isAfter': new Date().format('yyyy-MM-dd hh:mm:ss')}"
      />
    </cl-form-item>
    <div class="date-range">
      <cl-form-item label="开始日期">
        <cl-date
          v-model="validateRange.isStart"
          format="yyyy-MM-dd"
          value-format="yyyy-MM-dd"
          :validate="{'required':true,'isEnd': validateRange.isEnd}"
        />
      </cl-form-item>
      <cl-form-item label="结束日期">
        <cl-date
          v-model="validateRange.isEnd"
          format="yyyy-MM-dd"
          value-format="yyyy-MM-dd"
          :validate="{'required':true,'isStart': validateRange.isStart}"
        />
      </cl-form-item>
    </div>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        validateRange: {
          isBefore: '',
          isAfter: '',
          isStart: '',
          isEnd: ''
        }
      }
    }
  }
</script>
<!-- validate-range.vue -->
```

### 整数

`numeric`校验整数。

```html
<template>
  <el-form :model="confirmForm">
    <cl-form-item label="整数">
      <cl-input v-model="confirmForm.num1" validate="numeric"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          num1: ''
        }
      }
    }
  }
</script>
<style>
  .el-row {
    margin-bottom: 15px;
  }
</style>
<!-- validation5.vue -->
```

### 限制输入数字范围

`between`校验输入的数字在规定范围。

```html
<template>
  <el-form :model="confirmForm">
    <cl-form-item label="大于1小于10">
      <cl-input v-model="confirmForm.num1" validate="between:1,10"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          num1: ''
        }
      }
    }
  }
</script>
<style>
  .el-row {
    margin-bottom: 15px;
  }
</style>
<!-- validation6.vue -->
```

### 指定固定值

`is`指定固定值。

```html
<template>
  <el-form :model="confirmForm">
    <cl-form-item label="固定值test">
      <cl-input v-model="confirmForm.num1" validate="is:test"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          num1: ''
        }
      }
    }
  }
</script>
<!-- validation7.vue -->
```

### 指定数字位数

`digits`指定数字位数。

```html
<template>
  <el-form :model="confirmForm">
    <cl-form-item label="固定值test">
      <cl-input v-model="confirmForm.num1" validate="digits:3"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          num1: ''
        }
      }
    }
  }
</script>
<!-- validation9.vue -->
```

### 手机号

`mobile`校验手机号。

```html
<template>
  <el-form :model="confirmForm">
    <cl-form-item label="手机号">
      <cl-input v-model="confirmForm.num1" validate="mobile"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          num1: ''
        }
      }
    }
  }
</script>
<!-- validation10.vue -->
```

### 必填

`required`校验必填。

```html
<template>
  <el-form :model="confirmForm">
    <cl-form-item label="必填">
      <cl-input v-model="confirmForm.num1" validate="required"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          num1: ''
        }
      }
    }
  }
</script>
<!-- validation11.vue -->
```

### 字母空格

`alpha_spaces`校验输入字段必须是字母或空格。

```html
<template>
  <el-form :model="confirmForm">
    <cl-form-item label="字母或空格">
      <cl-input v-model="confirmForm.num1" validate="alpha_spaces"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          num1: ''
        }
      }
    }
  }
</script>
<!-- validation12.vue -->
```

### 字母数字横线下划线

`alpha_dash`校验输入字段必须是字母、数字、横线、下划线。

```html
<template>
  <el-form :model="confirmForm">
    <cl-form-item label="字母数字横线下划线" label-width="150px">
      <cl-input v-model="confirmForm.num1" validate="alpha_dash"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          num1: ''
        }
      }
    }
  }
</script>
<!-- validation13.vue -->
```

### 字母数字

`alpha_num`校验输入字段必须为字母或数字，`alpha`校验输入字段必须为字母。

```html
<template>
  <el-form :model="confirmForm">
    <cl-form-item label="字母数字">
      <cl-input v-model="confirmForm.num1" validate="alpha_num"></cl-input>
    </cl-form-item>
    <cl-form-item label="字母">
      <dl-input v-model="confirmForm.num2" validate="alpha"></dl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          num1: '',
          num2: ''
        }
      }
    }
  }
</script>
<!-- validation14.vue -->
```

### 数字

`decimal`校验输入字段必须为数字

```html
<template>
  <el-form :model="confirmForm">
    <cl-form-item label="字母数字">
      <cl-input v-model="confirmForm.num1" validate="decimal"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          num1: 0
        }
      }
    }
  }
</script>
<!-- validation_decimal.vue -->
```

### 自定义 JS 方法校验

`method`接收两个参数，第一个参数为要校验的 JS 方法，第二个参数为未通过校验时的提示信息。

```html
<template>
  <el-form :model="confirmForm">
    <cl-form-item label="js校验数值大于50" label-width="300px">
      <cl-input v-model="confirmForm.num1" :validate="{method: {callback:checkNum ,message: '数值必须大于50'}}"></cl-input>
    </cl-form-item>
    <cl-form-item label="js异步校验用户名是否已存在(测试已存在test用户名)" label-width="300px">
      <cl-input v-model="confirmForm.num2" :validate="{method: {callback:checkName ,message: '该用户名已存在'}}"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        confirmForm: {
          num1: '',
          num2: ''
        }
      }
    },
    methods: {
      checkNum(val, args) {
        return val > 50
      },
      checkName(val, args) {
        return new Promise((resolve) => {
          setTimeout(() => {
            resolve(val != 'test')
          }, 300)
        })
      }
    }
  }
</script>
<!-- validation15.vue -->
```

### 多个规则校验

- 使用字符串格式时，多个校验规则之间用管道符|分割，按照从左至右的顺序依次校验。
- 使用对象格式时，对象格式的校验规则，在校验时是无序的。

```html
<template>
  <el-form :model="validateMultiple" label-width="80px">
    <cl-form-item label="字符串格式">
      <cl-input v-model="validateMultiple.val" validate="required|min:2|max:10"></cl-input>
    </cl-form-item>
    <cl-form-item label="对象格式">
      <cl-input v-model="validateMultiple.val2" :validate="{required: true, min: '2', max: '10'}"></cl-input>
    </cl-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        validateMultiple: {
          val: '',
          val2: ''
        }
      }
    }
  }
</script>
<style>
  .date-range {
    display: flex;
  }
</style>
<!-- validate1.vue -->
```

### 校验表单

- 在使用表单录入数据时，需要对表单中的所有校验字段进行校验，通过校验后才允许提交数据。
- 使用 data-vv-scope="form1"来标记当前表单，在进行表单校验时，可以指定 form1 来验证指定作用域内的校验结果，避免同一个页面中具有多个表单时交叉校验的问题。另外 v-form 指令用于标记当前表单，实现表单内的数学计算时多个字段相互计算的需求。

```html
<template>
  <el-form :model="formData" label-width="80px" data-vv-scope="form1" v-form>
    <cl-form-item label="姓名">
      <cl-input v-model="formData.name" validate="required|min:2|max:4"></cl-input>
    </cl-form-item>
    <cl-form-item label="爱好">
      <cl-input v-model="formData.hobby" validate="required"></cl-input>
    </cl-form-item>
    <cl-form-item>
      <el-button type="primary" @click="onSubmit" :loading="loading"> 提交 </el-button>
      <el-button>取消</el-button>
    </cl-form-item>
  </el-form>
</template>
<script>
  // 此处demo中这样引入工具方法 utils，实际项目中引入路径为 import utils from "swordpaas-ui/src/utils.js"
  import utils from '../../src/utils'
  export default {
    data() {
      return {
        formData: {
          name: '',
          hobby: ''
        },
        loading: false
      }
    },
    methods: {
      onSubmit() {
        this.loading = true
        setTimeout(() => {
          utils
            .validateForm(this, 'form1')
            .then((r) => {
              this.$message.success(JSON.stringify(this.formData))
            })
            .catch((items) => {
              this.$message.error(`有${items.length}个字段未通过校验，请正确填写表单内容。`)
            })
            .finally(() => {
              this.loading = false
            })
        }, 500)
      }
    }
  }
</script>

<!-- validate-form.vue -->
```

### 校验规则说明

| 规则         | 校验内容                      | 参数                                                                                | 校验表达式                                                  | 说明                                                                                                                                                                                                                                                                                                                                                            |
| :----------- | :---------------------------- | :---------------------------------------------------------------------------------- | :---------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| confirmed    | 相同的值                      | 一个参数，要校验当前字段和另外一个字段的值相同时，需要指定另外一个字段的 model 属性 | :validate="'confirmed:'+ confirmForm.password"              | 另一个控件 v-model 绑定值 confirmForm.password                                                                                                                                                                                                                                                                                                                  |
| email        | 邮箱                          | —                                                                                   | validate="email"                                            | —                                                                                                                                                                                                                                                                                                                                                               |
| regex        | 正则表达式                    | 两个参数，第一个参数为正则表达式，第二个参数为校验未通过时的提示信息                | validate="regex:^[0-9]+$,校验失败"                          | 注意输入的正则表达式不能是/^[0-9]+$/格式，我们在解析校验规则时，会通过newRegExp(args[0])的方式来生成正则表达式对象。注意:字符串格式的表达式以英文逗号,来分割参数，如果正则表达式或者提示信息中包含了英文逗号，会导致校验规则的解析错误。这种情况下，我们需要按照Object格式来编写校验表达式:validate="{regex:{exp:'^[0-9]+$',message:'校验失败，请输入数字。'}}" |
| min          | 最小文本长度                  | 一个数字类型的参数，指定文本的最小长度                                              | validate="min:3"                                            | —                                                                                                                                                                                                                                                                                                                                                               |
| min_value    | 最小数值                      | 一个数字类型的参数，指定输入数字的最小值                                            | validate="min_value:255"                                    | —                                                                                                                                                                                                                                                                                                                                                               |
| max          | 最大文本长度                  | 一个数字类型的参数，指定文本的最大长度                                              | validate="max:3"                                            | —                                                                                                                                                                                                                                                                                                                                                               |
| max_value    | 最大数值                      | 一个数字类型的参数，指定输入数字的最大值                                            | validate="max_value:255"                                    | —                                                                                                                                                                                                                                                                                                                                                               |
| isAfter      | 日期晚于                      | 一个参数，要对比的另外一个字段的 model 属性                                         | :validate="'isAfter:'+startTime"                            | —                                                                                                                                                                                                                                                                                                                                                               |
| isBefore     | 日期早于                      | 一个参数，要对比的另外一个字段的 model 属性                                         | :validate="'isBefore:'+validateRange.isBefore"              | 另一个控件 v-model 绑定值 validateRange.isBefore                                                                                                                                                                                                                                                                                                                |
| isStart      | 日期不早于                    | 一个参数，要对比的另外一个字段的 model 属性                                         | :validate="'isStart:'+new Date().format('yyyy-MM-dd')"      | —                                                                                                                                                                                                                                                                                                                                                               |
| isEnd        | 日期不晚于                    | 一个参数，要对比的另外一个字段的 model 属性                                         | :validate="'isEnd:'+new Date().format('yyyy-MM-dd')"        | —                                                                                                                                                                                                                                                                                                                                                               |
| numeric      | 整数                          | —                                                                                   | validate="numeric"                                          | —                                                                                                                                                                                                                                                                                                                                                               |
| between      | 指定范围的数字(包含最小/大值) | 两个参数，最小值/最大值，均为数字                                                   | validate="between:1,10"                                     | —                                                                                                                                                                                                                                                                                                                                                               |
| is           | 指定的值                      | 一个参数，指定的值                                                                  | validate="is:test"                                          | 例`is:test`这样的表达式，则要求输入框的内容必须为 test                                                                                                                                                                                                                                                                                                          |
| digits       | 指定位数的数字                | 一个数字类型的参数，指定数字的位数                                                  | validate="digits:3"                                         | —                                                                                                                                                                                                                                                                                                                                                               |
| mobile       | 手机号                        | —                                                                                   | validate="mobile"                                           | —                                                                                                                                                                                                                                                                                                                                                               |
| required     | 必填                          | —                                                                                   | validate="required"                                         | —                                                                                                                                                                                                                                                                                                                                                               |
| alpha_spaces | 字母空格                      | —                                                                                   | validate="alpha_spaces"                                     | —                                                                                                                                                                                                                                                                                                                                                               |
| alpha_dash   | 字母数字横线下划线            | —                                                                                   | validate="alpha_dash"                                       | —                                                                                                                                                                                                                                                                                                                                                               |
| alpha_num    | 字母数字                      | —                                                                                   | validate="alpha_num"                                        | —                                                                                                                                                                                                                                                                                                                                                               |
| alpha        | 字母                          | —                                                                                   | validate="alpha"                                            | —                                                                                                                                                                                                                                                                                                                                                               |
| decimal      | 数字                          | —                                                                                   | validate="decimal"                                          | —                                                                                                                                                                                                                                                                                                                                                               |
| method       | JS 方法校                     | 两个参数，第一个参数为要校验的 JS 方法，第二个参数为未通过校验时的提示信息          | :validate="{method:{callback:callback,message:'校验失败'}}" | JS 方法校验的表达式只能以 Object 格式，callback 的示例代码如下：`callback:(value,args)=>{return value=="test"}`，如果要在 JS 方法中异步调用接口来完成校验，则可以返回 Promise 对象，再通过 Resolve 来返回校验结果，如下所示：`callback:(value,args)=>{return new Promise(resolve=>{setTimeout(()=>{resolve(!!value);},300);});}`                                |
