likes
comments
collection
share

Element-UI 中的form 为什么一定要绑定model ?

作者站长头像
站长
· 阅读数 50

你是否有这样的困惑,为什么form表单中model一定是必传的? 为什么添加校验规则的时候,form-item中的prop也是必传的?组件内部究竟是怎么设计的? 这两个属性有什么必然的联系呢?

form中的model

model是el-form 用来挂载数据的一个对象。理论上vue 并没有限制表单元素v-model绑定的数据一定要挂在一个对象上,你当然可以在form中某个input上绑定一个变量,此时model的任何变化都与这个变量无关。但是,一旦你涉及到表单校验、表单reset等方法调用时,你会发现这个model对象是必须要传的。那我们似乎明白了,model的存在和表单校验有一定联系?重置表单值,清空校验也和mode有一定的关系?

别急,打开element源码看看(让开,我要开始装杯了)

在form.vue中 总共有两处用到了model对象,一个是resetFields这个方法

Element-UI 中的form 为什么一定要绑定model ?

一个是validate这个方法,实际上这两个方法都是调用的子组件form-item中的方法

Element-UI 中的form 为什么一定要绑定model ?

form源码比较简单,主要是接收一些全局属性,和暴露了一些全局的方法。

dispatch

引人注意的是element 封装了一个全局通信的方法,可以学习一下。在form-item组件中为了达到和form组件的数据通信,调用了一个dispatch方法。

Element-UI 中的form 为什么一定要绑定model ?

dispatch方法在src-mixins-emitter.js中,主要是通过向上查找的方式,找到对应的组件,然后利用vue的emit事件传递一个方法,方法可带上参数。

Element-UI 中的form 为什么一定要绑定model ?

然后在父组件el-form中,通过this.$on就可以用来接收这个事件了。

Element-UI 中的form 为什么一定要绑定model ?

这样的话就能解决组件深层嵌套的时候数据通信的问题。

form-item中的model

form-item中也封装了一个validate方法,这也是表单校验的核心方法。

Element-UI 中的form 为什么一定要绑定model ?

首先通过getFilteredRule获取到当前表单元素的rules,可以看下在getRules中,通过收集form上绑定的rules 和 form-item绑定的rules合成一个数组。这个数组就是用来存储校验规则的。

Element-UI 中的form 为什么一定要绑定model ?

回到validate方法中,把元素自身的prop作为属性存到一个descriptor对象中。然后作为参数调用并传入AsyncValidator这个类(第三方校验表单的库,感兴趣的自行研究)。validator回调函数中会返回当前的校验结果,传入的错误提示等。

Element-UI 中的form 为什么一定要绑定model ?

表单元素的prop和表单验证息息相关,密不可分。

resetField是用来重置表单值的,重置以后,表单绑定的所有值恢复到初始化状态。记得三年前一直把resetField当做用来清空表单值的方法使用,直到出了线上bug,才对这个方法有了新的认识。

Element-UI 中的form 为什么一定要绑定model ?

这个方法中通过model对象、元素绑定的prop作为属性key ,找到对应的初始值,然后进行初始化赋值。

注意:model中的属性如果没有初始值的话会被复制为undefined,此时v-model的双向绑定失效

model的另外一个作用就是用来获取表单元素的值

Element-UI 中的form 为什么一定要绑定model ?

model 通过prop调用getPropByPath(model, path, true).v拿到对应的值。这个值是表单校验的重要依据。换句话说,你的校验能不能通过就是拿到这个值去rules中对比的。

总结

model在el-form中的作用

  1. model用来获取表单元素的值

  2. model是表单校验的重要数据对象,通过model和prop的结合找到表单元素绑定的值

  3. model在resetField方法中用来重置初始值

  4. model在fieldValue中获取初始值