小工具知识网

当前位置: 首页 > 行业知识 > el-table通过这样封装可以实现校验-表格校验的原理

行业知识

el-table通过这样封装可以实现校验-表格校验的原理

2026-11-03 18:01:26 来源:互联网转载

���们一般在后台系统中,很常见的操作时表格里面嵌套表单,之前我的网上找到了一些封装的用法:

                                                  // data中的数据formData: {  tableData: [    { name: "", age: "" },    { name: "", age: "" },    { name: "", age: "" },    { name: "", age: "" },  ],},ruleData: {  name: { message: "请输入名字", required: true },  age: { message: "请输入年龄", required: true },},column: [  { label: "名字", prop: "name" },  { label: "年龄", prop: "age" },],

在这里我不太理解prop为什么要写成"'tableData.' + scope.$index + '.' + item.prop"这个样子就实现了校验的效果。后来在一次项目中偶然去查看了一下el-form的源码,才明白其中的道理;

首先我们看到el-form组件的文件路径是这样的,那么其实form-item是一个单独的组件,我们通过form -> form-item嵌套的时候,其实最后实现校验的过程是一个个去校验 form-item,form组件最终的校验:

// 最主要的核心功能validate(callback){  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);    }  });});}

其中 this.fields就是el-form-item集合:

// el-form的created中this.$on('el.form.addField', (field) => {  if (field) {    this.fields.push(field);  }});// el-form-item的mounted中this.dispatch('ElForm', 'el.form.addField', [this]);// 内部自己使用 dispatch实现组件通讯

其中最主要的就是调用el-form-item的validate方法:

validate(trigger, callback = noop) {        this.validateDisabled = false;        const rules = this.getFilteredRule(trigger);        if ((!rules || rules.length === 0) && this.required === undefined) {          callback();          return true;        }        this.validateState = 'validating';        const descriptor = {};        if (rules && rules.length > 0) {          rules.forEach(rule => {            delete rule.trigger;          });        }        descriptor[this.prop] = rules;        const validator = new AsyncValidator(descriptor);        const model = {};        model[this.prop] = this.fieldValue;        validator.validate(model, { firstFields: true }, (errors, invalidFields) => {          this.validateState = !errors ? 'success' : 'error';          this.validateMessage = errors ? errors[0].message : '';          callback(this.validateMessage, invalidFields);          this.elForm && this.elForm.$emit('validate', this.prop, !errors, this.validateMessage || null);        });      }

其中主要的核心功能是单个的 rules(校验规则)和model(数据),

rules的获取:

// 首先通过getFilteredRule方法过滤rulesgetFilteredRule(trigger) {  // 获取 rules  const rules = this.getRules();  return rules.filter(rule => {    if (!rule.trigger || trigger === '') return true;    if (Array.isArray(rule.trigger)) {      return rule.trigger.indexOf(trigger) > -1;    } else {      return rule.trigger === trigger;    }  }).map(rule => objectAssign({}, rule));},// getFilteredRule最核心的方式就是getRulesgetRules() {  // 这个就是我们在 el-form中传递的rules  let formRules = this.form.rules;  // 这个就是我们自己在 el-form-item传递的rules  const selfRules = this.rules;  // 这里判断是不是必输的  const requiredRule = this.required !== undefined ? { required: !!this.required } : [];  // 这里通过formRules结合prop获取最新的prop(其实是一个对象,里面有key,value比较重要的值)  const prop = getPropByPath(formRules, this.prop || '');  formRules = formRules ? (prop.o[this.prop || ''] || prop.v) : [];  // 最终将rules做一个整合  return [].concat(selfRules || formRules || []).concat(requiredRule);},

最终我们通过分析发现其实去匹配 el-form中整体的rules是通过getPropByPath这个方法的:

function getPropByPath(obj, path) {  let tempObj = obj;  path = path.replace(/\[(\w+)\]/g, '.$1');  path = path.replace(/^\./, '');  let keyArr = path.split('.');  let i = 0;  for (let len = keyArr.length; i  

path.split('.')这里会对prop进行切割,我们最终得到的值其实是这样的:

最终通过formRules = formRules ? (prop.o[this.prop || ''] || prop.v) : [];将formRules这个值变成了undefined,

再返回validate方法里面,看model,通过这里model[this.prop] = this.fieldValue,我们来看fieldValue:

function getPropByPath(obj, path) {  // 这里的值其实一个对象数组:  // { tableData: [  // { name: "", age: "" },  // { name: "", age: "" },  // { name: "", age: "" },  // { name: "", age: "" },// ] },  let tempObj = obj;  path = path.replace(/\[(\w+)\]/g, '.$1');  path = path.replace(/^\./, '');  // 那第一个来说就是 tableData.0.name  let keyArr = path.split('.');  let i = 0;  for (let len = keyArr.length; i  

最终fieldValue就表示了表格组件中每个小块的值,通过 prop和model去匹配对应的值,和rules结合AsyncValidator实现表单校验。这里我们也可以看出给el-form传递model,给el-form-item传递prop,rules的重要性。

写到这里我还有一个疑问,那就是在getRules方法中,通过getPropByPath其实最终是把formRules转换成一个undefined的,那么是不是在此次封装中给el-form传递的rules没用了,其实真正起主导作用的还是给el-form-item传递的rules,那么把el-form-item中的rules删除掉是不是就校验不了了。通过验证证实了我的猜想。

上一篇:宝塔面板视频横屏观看详解,轻松实现视频横屏观看体验!

下一篇:此 Google 帐号尚未与设备关联。要安装应用,请先访问设备上的 Play 商店应用。 了解详情(已解决)