refactor: form
							parent
							
								
									97aeaf74b4
								
							
						
					
					
						commit
						130982a037
					
				|  | @ -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() { | ||||
|  |  | |||
|  | @ -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']), | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
|  | @ -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", | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 tanjinzhou
						tanjinzhou