場景
Form 組件提供了表單驗證的功能,只需要通過 rules 屬性傳入約定的驗證規則,並將 Form-Item 的 prop 屬性設置為需校驗的字段名即可。
官方示例代碼
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <el-form-item label="活動名稱" prop="name"> <el-input v-model="ruleForm.name"></el-input> </el-form-item> <el-form-item label="活動區域" prop="region"> <el-select v-model="ruleForm.region" placeholder="請選擇活動區域"> <el-option label="區域一" value="shanghai"></el-option> <el-option label="區域二" value="beijing"></el-option> </el-select> </el-form-item> <el-form-item label="活動時間" required> <el-col :span="11"> <el-form-item prop="date1"> <el-date-picker type="date" placeholder="選擇日期" v-model="ruleForm.date1" style="width: 100%;"></el-date-picker> </el-form-item> </el-col> <el-col class="line" :span="2">-</el-col> <el-col :span="11"> <el-form-item prop="date2"> <el-time-picker placeholder="選擇時間" v-model="ruleForm.date2" style="width: 100%;"></el-time-picker> </el-form-item> </el-col> </el-form-item> <el-form-item label="即時配送" prop="delivery"> <el-switch v-model="ruleForm.delivery"></el-switch> </el-form-item> <el-form-item label="活動性質" prop="type"> <el-checkbox-group v-model="ruleForm.type"> <el-checkbox label="美食/餐廳線上活動" name="type"></el-checkbox> <el-checkbox label="地推活動" name="type"></el-checkbox> <el-checkbox label="線下主題活動" name="type"></el-checkbox> <el-checkbox label="單純品牌曝光" name="type"></el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="特殊資源" prop="resource"> <el-radio-group v-model="ruleForm.resource"> <el-radio label="線上品牌商贊助"></el-radio> <el-radio label="線下場地免費"></el-radio> </el-radio-group> </el-form-item> <el-form-item label="活動形式" prop="desc"> <el-input type="textarea" v-model="ruleForm.desc"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')">立即創建</el-button> <el-button @click="resetForm('ruleForm')">重置</el-button> </el-form-item> </el-form> <script> export default { data() { return { ruleForm: { name: '', region: '', date1: '', date2: '', delivery: false, type: [], resource: '', desc: '' }, rules: { name: [ { required: true, message: '請輸入活動名稱', trigger: 'blur' }, { min: 3, max: 5, message: '長度在 3 到 5 個字符', trigger: 'blur' } ], region: [ { required: true, message: '請選擇活動區域', trigger: 'change' } ], date1: [ { type: 'date', required: true, message: '請選擇日期', trigger: 'change' } ], date2: [ { type: 'date', required: true, message: '請選擇時間', trigger: 'change' } ], type: [ { type: 'array', required: true, message: '請至少選擇一個活動性質', trigger: 'change' } ], resource: [ { required: true, message: '請選擇活動資源', trigger: 'change' } ], desc: [ { required: true, message: '請填寫活動形式', trigger: 'blur' } ] } }; }, methods: { submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); } else { console.log('error submit!!'); return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); } } } </script>
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
關注公眾號
霸道的程序猿
獲取編程相關電子書、教程推送與免費下載。
實現
首先新建一個form
<el-form ref="form" :model="form" :rules="rules" label-width="100px"> <el-row> <el-col span="10"> <el-form-item label="班次編號:" prop="bcbh"> <el-input v-model="form.bcbh" placeholder="請輸入班次編號" /> </el-form-item> </el-col> <el-col span="10"> <el-form-item label="班次名稱:" prop="bcmc" label-width="100px"> <el-input v-model="form.bcmc" placeholder="請輸入班次名稱" /> </el-form-item> </el-col> </el-row> <el-row> <el-col span="10"> <el-form-item label="班次類型:" prop="bclx"> <el-select v-model="form.bclx" placeholder="請選擇班次類型" clearable @change="bclxChange"> <el-option v-for="dict in bclxOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" /> </el-select> </el-form-item> </el-col> </el-row> <el-row> <el-col span="10"> <el-form-item label="小時數:" prop="xss"> <el-input-number v-model="form.xss" :precision="1" :step="1" :max="24" placeholder="請輸入小時數" ></el-input-number> </el-form-item> </el-col> </el-row> <el-row> <el-col span="10"> <el-form-item label="計工數:" prop="jgs" span="10"> <el-input-number v-model="form.jgs" :precision="1" :step="1" :max="24" placeholder="請輸入計工數" ></el-input-number> </el-form-item> </el-col> </el-row> </el-form>
在form上設置rules驗證規則
:rules="rules"
綁定的是一個對象數組,所以在data中
// 表單校驗 rules: { bcbh: [ { required: true, message: "班次編號不能為空", trigger: "blur" }, ], bcmc: [ { required: true, message: "班次名稱不能為空", trigger: "blur" }, ], bclx: [{ required: true, message: "請選擇班次類型", trigger: "blur" }], xss: [ { required: true, message: "小時數不能為空", trigger: "blur", }, ], jgs: [{ required: true, message: "計工數不能為空", trigger: "blur" }], },
這里的格式是固定的,下面的bcbh要與上面要驗證的prop相對應。
這里設置的規則都是要求必填,觸發都是失去焦點。
更多校驗規則參考如下:
https://github.com/yiminghe/async-validator
下面是英文原文
Usage
Basic usage involves defining a descriptor, assigning it to a schema and passing the object to be validated and a callback function to the validate
method of the schema:
import Schema from 'async-validator'; const descriptor = { name: { type: 'string', required: true, validator: (rule, value) => value === 'muji', }, age: { type: 'number', asyncValidator: (rule, value) => { return new Promise((resolve, reject) => { if (value < 18) { reject('too young'); // reject with error message } else { resolve(); } }); }, }, }; const validator = new Schema(descriptor); validator.validate({ name: 'muji' }, (errors, fields) => { if (errors) { // validation failed, errors is an array of all errors // fields is an object keyed by field name with an array of // errors per field return handleErrors(errors, fields); } // validation passed }); // PROMISE USAGE validator.validate({ name: 'muji', age: 16 }).then(() => { // validation passed or without error message }).catch(({ errors, fields }) => { return handleErrors(errors, fields); });
API
Validate
function(source, [options], callback): Promise
source
: The object to validate (required).options
: An object describing processing options for the validation (optional).callback
: A callback function to invoke when validation completes (required).
The method will return a Promise object like:
then()
,validation passedcatch({ errors, fields })
,validation failed, errors is an array of all errors, fields is an object keyed by field name with an array of
Options
-
suppressWarning
: Boolean, whether to suppress internal warning about invalid value. -
first
: Boolean, Invokecallback
when the first validation rule generates an error, no more validation rules are processed. If your validation involves multiple asynchronous calls (for example, database queries) and you only need the first error use this option. -
firstFields
: Boolean|String[], Invokecallback
when the first validation rule of the specified field generates an error, no more validation rules of the same field are processed.true
means all fields.
Rules
Rules may be functions that perform validation.
function(rule, value, callback, source, options)
rule
: The validation rule in the source descriptor that corresponds to the field name being validated. It is always assigned afield
property with the name of the field being validated.value
: The value of the source object property being validated.callback
: A callback function to invoke once validation is complete. It expects to be passed an array ofError
instances to indicate validation failure. If the check is synchronous, you can directly return afalse
orError
orError Array
.source
: The source object that was passed to thevalidate
method.options
: Additional options.options.messages
: The object containing validation error messages, will be deep merged with defaultMessages.
The options passed to validate
or asyncValidate
are passed on to the validation functions so that you may reference transient data (such as model references) in validation functions. However, some option names are reserved; if you use these properties of the options object they are overwritten. The reserved properties are messages
, exception
and error
.
import Schema from 'async-validator'; const descriptor = { name(rule, value, callback, source, options) { const errors = []; if (!/^[a-z0-9]+$/.test(value)) { errors.push(new Error( util.format('%s must be lowercase alphanumeric characters', rule.field), )); } return errors; }, }; const validator = new Schema(descriptor); validator.validate({ name: 'Firstname' }, (errors, fields) => { if (errors) { return handleErrors(errors, fields); } // validation passed });
It is often useful to test against multiple validation rules for a single field, to do so make the rule an array of objects, for example:
const descriptor = { email: [ { type: 'string', required: true, pattern: Schema.pattern.email }, { validator(rule, value, callback, source, options) { const errors = []; // test if email address already exists in a database // and add a validation error to the errors array if it does return errors; }, }, ], };
Type
Indicates the type
of validator to use. Recognised type values are:
string
: Must be of typestring
.This is the default type.
number
: Must be of typenumber
.boolean
: Must be of typeboolean
.method
: Must be of typefunction
.regexp
: Must be an instance ofRegExp
or a string that does not generate an exception when creating a newRegExp
.integer
: Must be of typenumber
and an integer.float
: Must be of typenumber
and a floating point number.array
: Must be an array as determined byArray.isArray
.object
: Must be of typeobject
and notArray.isArray
.enum
: Value must exist in theenum
.date
: Value must be valid as determined byDate
url
: Must be of typeurl
.hex
: Must be of typehex
.email
: Must be of typeemail
.any
: Can be any type.
Required
The required
rule property indicates that the field must exist on the source object being validated.
Pattern
The pattern
rule property indicates a regular expression that the value must match to pass validation.
Range
A range is defined using the min
and max
properties. For string
and array
types comparison is performed against the length
, for number
types the number must not be less than min
nor greater than max
.
Length
To validate an exact length of a field specify the len
property. For string
and array
types comparison is performed on the length
property, for the number
type this property indicates an exact match for the number
, ie, it may only be strictly equal to len
.
If the len
property is combined with the min
and max
range properties, len
takes precedence.
Enumerable
Since version 3.0.0 if you want to validate the values
0
orfalse
insideenum
types, you have to include them explicitly.
To validate a value from a list of possible values use the enum
type with a enum
property listing the valid values for the field, for example:
const descriptor = { role: { type: 'enum', enum: ['admin', 'user', 'guest'] }, };
Whitespace
It is typical to treat required fields that only contain whitespace as errors. To add an additional test for a string that consists solely of whitespace add a whitespace
property to a rule with a value of true
. The rule must be a string
type.
You may wish to sanitize user input instead of testing for whitespace, see transform for an example that would allow you to strip whitespace.
Deep Rules
If you need to validate deep object properties you may do so for validation rules that are of the object
or array
type by assigning nested rules to a fields
property of the rule.
const descriptor = { address: { type: 'object', required: true, fields: { street: { type: 'string', required: true }, city: { type: 'string', required: true }, zip: { type: 'string', required: true, len: 8, message: 'invalid zip' }, }, }, name: { type: 'string', required: true }, }; const validator = new Schema(descriptor); validator.validate({ address: {} }, (errors, fields) => { // errors for address.street, address.city, address.zip });
Note that if you do not specify the required
property on the parent rule it is perfectly valid for the field not to be declared on the source object and the deep validation rules will not be executed as there is nothing to validate against.
Deep rule validation creates a schema for the nested rules so you can also specify the options
passed to the schema.validate()
method.
const descriptor = { address: { type: 'object', required: true, options: { first: true }, fields: { street: { type: 'string', required: true }, city: { type: 'string', required: true }, zip: { type: 'string', required: true, len: 8, message: 'invalid zip' }, }, }, name: { type: 'string', required: true }, }; const validator = new Schema(descriptor); validator.validate({ address: {} }) .catch(({ errors, fields }) => { // now only errors for street and name });
The parent rule is also validated so if you have a set of rules such as:
const descriptor = { roles: { type: 'array', required: true, len: 3, fields: { 0: { type: 'string', required: true }, 1: { type: 'string', required: true }, 2: { type: 'string', required: true }, }, }, };
And supply a source object of { roles: ['admin', 'user'] }
then two errors will be created. One for the array length mismatch and one for the missing required array entry at index 2.
defaultField
The defaultField
property can be used with the array
or object
type for validating all values of the container. It may be an object
or array
containing validation rules. For example:
const descriptor = { urls: { type: 'array', required: true, defaultField: { type: 'url' }, }, };
Note that defaultField
is expanded to fields
, see deep rules.
Transform
Sometimes it is necessary to transform a value before validation, possibly to coerce the value or to sanitize it in some way. To do this add a transform
function to the validation rule. The property is transformed prior to validation and re-assigned to the source object to mutate the value of the property in place.
import Schema from 'async-validator'; const descriptor = { name: { type: 'string', required: true, pattern: /^[a-z]+$/, transform(value) { return value.trim(); }, }, }; const validator = new Schema(descriptor); const source = { name: ' user ' }; validator.validate(source) .then(() => assert.equal(source.name, 'user'));
Without the transform
function validation would fail due to the pattern not matching as the input contains leading and trailing whitespace, but by adding the transform function validation passes and the field value is sanitized at the same time.
Messages
Depending upon your application requirements, you may need i18n support or you may prefer different validation error messages.
The easiest way to achieve this is to assign a message
to a rule:
{ name: { type: 'string', required: true, message: 'Name is required' } }
Message can be any type, such as jsx format.
{ name: { type: 'string', required: true, message: '<b>Name is required</b>' } }
Message can also be a function, e.g. if you use vue-i18n:
{ name: { type: 'string', required: true, message: () => this.$t( 'name is required' ) } }
Potentially you may require the same schema validation rules for different languages, in which case duplicating the schema rules for each language does not make sense.
In this scenario you could just provide your own messages for the language and assign it to the schema:
import Schema from 'async-validator'; const cn = { required: '%s 必填', }; const descriptor = { name: { type: 'string', required: true } }; const validator = new Schema(descriptor); // deep merge with defaultMessages validator.messages(cn); ...
If you are defining your own validation functions it is better practice to assign the message strings to a messages object and then access the messages via the options.messages
property within the validation function.
asyncValidator
You can customize the asynchronous validation function for the specified field:
const fields = { asyncField: { asyncValidator(rule, value, callback) { ajax({ url: 'xx', value: value, }).then(function(data) { callback(); }, function(error) { callback(new Error(error)); }); }, }, promiseField: { asyncValidator(rule, value) { return ajax({ url: 'xx', value: value, }); }, }, };
validator
You can custom validate function for specified field:
const fields = { field: { validator(rule, value, callback) { return value === 'test'; }, message: 'Value is not equal to "test".', }, field2: { validator(rule, value, callback) { return new Error(`${value} is not equal to 'test'.`); }, }, arrField: { validator(rule, value) { return [ new Error('Message 1'), new Error('Message 2'), ]; }, }, };
FAQ
How to avoid warning
import Schema from 'async-validator'; Schema.warning = function(){};
How to check if it is true
Use enum
type passing true
as option.
{
type: 'enum', enum: [true], message: '', }