element-ui表单源码解析之el-form
element-ui表单源码解析之el-form
表单时大家常用的,根据本站的百度统计后台显示来到道招网的程序很多都在关注《element-ui动态表单async-validate校验 please transfer a valid prop path to form item!》 看来很多网友对element-ui的校验(或者说是async-validator)使用不太熟悉,想了想还是有必要分享下element-ui的表单校验机制的。
首先表单校验分el-form, el-form-item以及里面的el-input, el-select等。 这里就以el-form, el-form-item和el-input组合为例。为了讲的更加详细,决定分一个系列来讲。毕竟码字多了就想草草结束。。。 先直接看el-form吧,这里的代码很少,毕竟主要内容是以slot插入的。
<template>
<form class="el-form" :class="[
labelPosition ? 'el-form--label-' + labelPosition : '',
{ 'el-form--inline': inline }
]">
<slot></slot>
</form>
</template>
属性就不多说了,跟校验相关的就是model和rules。还有就是validateOnRuleChange,它默认是true,并且有这样的watch存在
watch: {
rules() {
if (this.validateOnRuleChange) {
this.validate(() => {});
}
}
},
默认规则改变会实时校验表单哦。
// 表单校验源码
validate(callback) {
if (!this.model) {
console.warn('[Element Warn][Form]model is required for validate to work!');
return;
}
let promise;
// if no callback, return promise
if (typeof callback !== 'function' && window.Promise) {
promise = new window.Promise((resolve, reject) => {
callback = function(valid) {
valid ? resolve(valid) : reject(valid);
};
});
}
let valid = true;
let count = 0;
// 如果需要验证的fields为空,调用验证时立刻返回callback
if (this.fields.length === 0 && callback) {
callback(true);
}
let invalidFields = {};
this.fields.forEach(field => {
field.validate('', (message, field) => {
if (message) {
valid = false;
}
invalidFields = objectAssign({}, invalidFields, field);
if (typeof callback === 'function' && ++count === this.fields.length) {
callback(valid, invalidFields);
}
});
});
if (promise) {
return promise;
}
},
官网的示例是这样的
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();
}
}
所以很多初学者是不是一直在用callback的方式啊,里面的参数为true时,才表示校验成功。这样是没错,但是如果你的项目是分多个表单,并且需要几个表单都校验通过才能提交,你是不是觉得不那么好写了。 其实官方已经给出了说明了
只是说就差给个demo了,毕竟部分初学者喜欢复制然后修改嘛。
我们根据上面的源码可以看出想使用校验,必须传递model属性。如果传递的callback不是方法的话,会定义一个promise,同时会定义callback为方法,参数依然是是否校验通过的结果。个人觉得这样还是很巧妙的,毕竟后面就可以完全按照传递了callback为前提继续写了,中途不用来回想如果用户是传递callback的模式呢还是直接使用promise的模式了,只是说最后发现如果有promise就返回即可。点个赞。
接着看this.fields,这是个数组,存储了哪些el-form-item是需要校验的。在created时进行存储的。
因为vue的父组件的created周期是在子组件的created之前的。
// el-form源码
created() {
this.$on('el.form.addField', (field) => {
if (field) {
this.fields.push(field);
}
});
/* istanbul ignore next */
this.$on('el.form.removeField', (field) => {
if (field.prop) {
this.fields.splice(this.fields.indexOf(field), 1);
}
});
},
里面同时监听了移除校验某个el-form-item的事件。 到此el-form源码里面剩下的就不多了。只剩下以下三个方法了,放一起吧。
// el-form源码
resetFields() {
if (!this.model) {
process.env.NODE_ENV !== 'production' &&
console.warn('[Element Warn][Form]model is required for resetFields to work.');
return;
}
this.fields.forEach(field => {
field.resetField();
});
},
clearValidate(props = []) {
const fields = props.length
? (typeof props === 'string'
? this.fields.filter(field => props === field.prop)
: this.fields.filter(field => props.indexOf(field.prop) > -1)
) : this.fields;
fields.forEach(field => {
field.clearValidate();
});
},
validateField(prop, cb) {
let field = this.fields.filter(field => field.prop === prop)[0];
if (!field) { throw new Error('must call validateField with valid prop string!'); }
field.validate('', cb);
}
分别是重置表单、清空校验、单独校验某个el-form-item。
- 重置表单:就是让里面每个item各自重置自己即可。
- 清空校验:支持清空针对某个prop的校验,可以是字符串,也可以是数组。如果什么都不传的话,就去情况整个表单的校验了。
- 单独校验某个item,根据传入的prop过滤出对应的field,如果有多个只取第一个,然后校验,执行回调。
需要说明下的是: 这里的field.validate需要在el-form-item里面看了。 el-form通过下面的方式实现了在它的子组件里面能够通过this.elForm来访问el-form的功能。Vue2.2.0+的功能
// el-form源码
provide() {
return {
elForm: this
};
},
el-form的源码应该是讲的很清楚了,有需要的同学可以查看源码。
- 分类:
- Web前端
相关文章
element-ui合并单元格使用详解
最近做的一个叫组合商品的项目,里面需要用到饿了么的合并单元格。 看了看官方的示例,发现所谓的单元格跟我之前的认知不一样,比如有两个组合A、B,其中A是由a1和a2组合在一起(即A = [a1, 阅读更多…
element-ui动态表单async-validate校验 please transfer a valid prop path to form item!
现在很多库,比如饿了么的element-ui的表单就是用的async-validate实现的表单校验,一般我们是这样的(以vue+element-ui为例) template <el - 阅读更多…
el-form-item、a-form-model-item实现多个input、select关联校验
有时候我们有一个表单里面的表单项除了简单的校验,还有些之间的关联校验,比如两个数字型的最大值和最小值,我们还要校验最大值不能小于最小值。 el-form-item <el-f 阅读更多…
element-ui表单源码解析之el-form-item
上一篇看了el-form,功能比较简单,现在来看看el-form-item <!--el-form-item源码--> <template> <div cla 阅读更多…
element-ui表单源码解析之el-input
关于表单校验el-input做的主要工作就是跟el-form-item交互,把input的相关事件发送给el-form-item,上一篇已经讲到在el-form-item的mounted的生命周期里 阅读更多…
wangEditor输入中文后直接粘贴bug来了解compositionstart
昨天有人反馈邮件编辑过程中的一个报障,具体内容就是在编辑器中输入中文然后直接粘贴先前复制好的信息,然后出现了bug,比如之前复制了订单号“1234”,再输入“您的订单号”后直接粘贴,编辑器内显示的结 阅读更多…