refactor: form

pull/2682/head
tanjinzhou 2020-07-10 18:26:35 +08:00
parent 97aeaf74b4
commit 130982a037
4 changed files with 147 additions and 13 deletions

View File

@ -7,6 +7,7 @@ import warning from '../_util/warning';
import FormItem from './FormItem';
import { initDefaultProps, getListeners, getSlot } from '../_util/props-util';
import { ConfigConsumerProps } from '../config-provider';
import { getParams } from './utils';
export const FormProps = {
layout: PropTypes.oneOf(['horizontal', 'inline', 'vertical']),
@ -45,6 +46,8 @@ export const ValidationRule = {
transform: PropTypes.func,
/** custom validate function (Note: callback must be called) */
validator: PropTypes.func,
//
scrollToFirstError: PropTypes.bool,
};
const Form = {
@ -96,12 +99,17 @@ const Form = {
this.$emit('submit', e);
}
},
resetFields() {
resetFields(props = this.fields) {
if (!this.model) {
warning(false, 'FormModel', 'model is required for resetFields to work.');
return;
}
this.fields.forEach(field => {
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.resetField();
});
},
@ -151,17 +159,81 @@ const Form = {
return promise;
}
},
validateField(props, cb) {
props = [].concat(props);
const fields = this.fields.filter(field => props.indexOf(field.prop) !== -1);
if (!fields.length) {
warning(false, 'FormModel', 'please pass correct props!');
return;
}
fields.forEach(field => {
field.validate('', cb);
scrollToField() {},
getFieldsValue(allFields) {
return allFields.map(({ prop, fieldValue }) => {
return { [prop]: fieldValue };
});
},
validateFields() {
this.validateField(...arguments);
},
validateField(ns, opt, cb) {
const pending = new Promise((resolve, reject) => {
const params = getParams(ns, opt, cb);
const { names, options } = params;
let { callback } = params;
if (!callback || typeof callback === 'function') {
const oldCb = callback;
callback = (errors, values) => {
if (oldCb) {
oldCb(errors, values);
} else if (errors) {
reject({ errors, values });
} else {
resolve(values);
}
};
}
const allFields = names
? this.fields.filter(field => names.indexOf(field.prop) !== -1)
: this.fields;
const fields = allFields.filter(field => {
const rules = field.getFilteredRule('');
return rules && rules.length;
});
if (!fields.length) {
callback(null, this.getFieldsValue(allFields));
return;
}
if (!('firstFields' in options)) {
options.firstFields = allFields.filter(field => {
return !!field.validateFirst;
});
}
let invalidFields = {};
let valid = true;
let count = 0;
fields.forEach(field => {
field.validate('', (message, field) => {
if (message) {
valid = false;
}
// TODO
invalidFields = Object.assign({}, invalidFields, field);
if (typeof callback === 'function' && ++count === fields.length) {
callback(valid, invalidFields);
}
});
});
});
pending.catch(e => {
if (console.error && process.env.NODE_ENV !== 'production') {
console.error(e);
}
return e;
});
return pending;
// names = [].concat(names);
// const fields = this.fields.filter(field => names.indexOf(field.prop) !== -1);
// if (!fields.length) {
// warning(false, 'FormModel', 'please pass correct props!');
// return;
// }
// fields.forEach(field => {
// field.validate('', cb);
// });
},
},
render() {

View File

@ -59,6 +59,7 @@ export const FormItemProps = {
rules: PropTypes.oneOfType([Array, Object]),
autoLink: PropTypes.bool,
required: PropTypes.bool,
validateFirst: PropTypes.bool,
validateStatus: PropTypes.oneOf(['', 'success', 'warning', 'error', 'validating']),
};

View File

@ -0,0 +1,61 @@
export function getValueFromEvent(e) {
// To support custom element
if (!e || !e.target) {
return e;
}
const { target } = e;
return target.type === 'checkbox' ? target.checked : target.value;
}
export function getErrorStrs(errors) {
if (errors) {
return errors.map(e => {
if (e && e.message) {
return e.message;
}
return e;
});
}
return errors;
}
export function getParams(ns, opt, cb) {
let names = ns;
let options = opt;
let callback = cb;
if (typeof names === 'string') {
names = [names];
}
if (cb === undefined) {
if (typeof names === 'function') {
callback = names;
options = {};
names = undefined;
} else if (Array.isArray(names)) {
if (typeof options === 'function') {
callback = options;
options = {};
} else {
options = options || {};
}
} else {
callback = options;
options = names || {};
names = undefined;
}
}
return {
names,
options,
callback,
};
}
export function hasRules(validate) {
if (validate) {
return validate.some(item => {
return item.rules && item.rules.length;
});
}
return false;
}

View File

@ -76,7 +76,7 @@
"@commitlint/config-conventional": "^8.0.0",
"@octokit/rest": "^16.0.0",
"@vue/cli-plugin-eslint": "^4.0.0",
"@vue/compiler-sfc": "^3.0.0-beta.14",
"@vue/compiler-sfc": "^3.0.0-beta.20",
"@vue/server-test-utils": "1.0.0-beta.16",
"@vue/test-utils": "^2.0.0-alpha.6",
"acorn": "^7.0.0",
@ -152,7 +152,7 @@
"terser-webpack-plugin": "^3.0.3",
"through2": "^3.0.0",
"url-loader": "^3.0.0",
"vue": "^3.0.0-beta.19",
"vue": "^3.0.0-beta.20",
"vue-antd-md-loader": "^1.1.0",
"vue-clipboard2": "0.3.1",
"vue-draggable-resizable": "^2.1.0",