作为一个数据收集工具,更多的是数据逻辑上的处理
- Form表单上的fields存在哪里
- Form.Item如何与field做关联
ant-design-vue中的Form
这里主要说template的写法的情况下,如果是jsx并不一样
this.$form.createForm 函数 生成的是什么?
export default {
// ...
data() {
return {
form:this.$form.createForm(this, {
name: 'demo-form-one'
})
}
}
// ...
}
- this.$form.createForm方法 在
components/form/Form.jsx
中,通过代码可知,这个方法返回的是一个Vue实例
// ...
createForm(context, options = {}) {
const V = Base.Vue || Vue;
return new V(Form.create({ ...options, templateContext: context })());
},
// ...
- Form.create经过层层的引用,最终调用的是createBaseForm 下 decorate 函数的方法
decorate 将返回生成Vue实例所需要的配置项
function createBaseForm(option = {}, mixins = []) {
// ...
return function decorate(WrappedComponent) { // 最终调用的就是这个方法
const Form = { /* ... */ }
// ...
if (!WrappedComponent) return Form;
}
// ...
}
- 在Vue的配置对象Form中,通过createFieldsStore生成fieldsStore,同时将fieldsStore映射到this上
const Form = {
data() {
// ...
this.fieldsStore = createFieldsStore(fields || {});
[
'getFieldsValue',
'getFieldValue',
'setFieldsInitialValue',
'getFieldsError',
'getFieldError',
'isFieldValidating',
'isFieldsValidating',
'isFieldsTouched',
'isFieldTouched',
].forEach(key => {
this[key] = (...args) => {
return this.fieldsStore[key](...args);
};
});
// ...
}
}
表单组件的数据是如何绑定上去的
<a-input
ref="input"
v-decorator="['note', {
rules: [
{ required: true },
{ message : 'Please input your note!'}
]
}]"
/>
- FormItem.jsx 中 对 子组件数组 调用了 decoratorChildren 方法
export default {
name: 'AFormItem',
render() {
let child = filterEmpty($slots.default || []);
// ...
child = cloneVNodes(child);
this.slotDefault = this.decoratorChildren(child);
// ...
return this.renderFormItem();
}
}
- decoratorChildren 方法中通过decoratorOption获得指令的参数,然后通过getFieldDecorator对组件进行再次封装
decoratorChildren(vnodes) {
const { FormProps } = this;
const getFieldDecorator = FormProps.form.getFieldDecorator;
for (let i = 0, len = vnodes.length; i < len; i++) {
// ...
const option = this.decoratorOption(vnode);
if (option && option[0]) {
vnodes[i] = getFieldDecorator(option[0], option[1], this)(vnode);
}
// ...
}
return vnodes;
}
- getFieldDecorator 方式是 定义在 createBaseForm里面, 通过getFieldProps 获得field相关的属性,最后通过cloneElement绑定到fieldElem上
getFieldDecorator: function getFieldDecorator(name, fieldOption, formItem) {
// ...
return function(fieldElem) {
// ...
var _getFieldProps = this.getFieldProps(name, fieldOption),
props = _getFieldProps.props,
restProps = _objectWithoutProperties(_getFieldProps, ['props']);
// ...
return cloneElement(fieldElem, _extends({}, newProps, { on: newEvents }));
// ...
}
// ...
}
- getFieldProps方法做了很多操作,其中有如下两个
- 取出fieldsStore中相关的值,作为value
- 绑定onCollectValidate事件到change上
{
getFieldProps: function getFieldProps(name) {
// ...
// 这边获取value
var inputProps = _extends({}, this.fieldsStore.getFieldValuePropValue(fieldOption));
// 这边绑定change事件,每次表单组件更新时,fieldStore里面相关的信息也会更新
validateTriggers.forEach(function (action) {
if (inputListeners[action]) return;
inputListeners[action] = _this3.getCacheBind(name, action, _this3.onCollectValidate);
});
// ...
}
}