From e79bfd8c96a195902b8f395f4965b3c2e14830f8 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Sun, 12 Jul 2020 16:13:59 +0800 Subject: [PATCH] refactor: form --- components/form-model/Form.jsx | 96 ++++++++++++++++-------------- components/form-model/FormItem.jsx | 4 +- components/form-model/utils.js | 43 +++++++++++++ examples/App.vue | 2 +- 4 files changed, 96 insertions(+), 49 deletions(-) diff --git a/components/form-model/Form.jsx b/components/form-model/Form.jsx index f8fe7173a..c2e1da528 100755 --- a/components/form-model/Form.jsx +++ b/components/form-model/Form.jsx @@ -1,4 +1,5 @@ import { inject, provide } from 'vue'; +// import scrollIntoView from 'dom-scroll-into-view'; import PropTypes from '../_util/vue-types'; import classNames from 'classnames'; import { ColProps } from '../grid/Col'; @@ -99,7 +100,7 @@ const Form = { this.$emit('submit', e); } }, - resetFields(props = this.fields) { + resetFields(props = []) { if (!this.model) { warning(false, 'FormModel', 'model is required for resetFields to work.'); return; @@ -123,50 +124,53 @@ const Form = { field.clearValidate(); }); }, - validate(callback) { - if (!this.model) { - warning(false, 'FormModel', 'model is required for resetFields to work.'); - return; - } - let promise; - // if no callback, return promise - if (typeof callback !== 'function' && window.Promise) { - promise = new window.Promise((resolve, reject) => { - callback = function(valid) { - valid ? resolve(valid) : reject(valid); - }; - }); - } - let valid = true; - let count = 0; - // 如果需要验证的fields为空,调用验证时立刻返回callback - if (this.fields.length === 0 && callback) { - callback(true); - } - let invalidFields = {}; - this.fields.forEach(field => { - field.validate('', (message, field) => { - if (message) { - valid = false; - } - invalidFields = Object.assign({}, invalidFields, field); - if (typeof callback === 'function' && ++count === this.fields.length) { - callback(valid, invalidFields); - } - }); - }); - if (promise) { - return promise; - } + validate() { + return this.validateField(...arguments); + // if (!this.model) { + // warning(false, 'FormModel', 'model is required for resetFields to work.'); + // return; + // } + // let promise; + // // if no callback, return promise + // if (typeof callback !== 'function' && window.Promise) { + // promise = new window.Promise((resolve, reject) => { + // callback = function(valid) { + // valid ? resolve(valid) : reject(valid); + // }; + // }); + // } + // let valid = true; + // let count = 0; + // // 如果需要验证的fields为空,调用验证时立刻返回callback + // if (this.fields.length === 0 && callback) { + // callback(true); + // } + // let invalidFields = {}; + // this.fields.forEach(field => { + // field.validate('', (message, field) => { + // if (message) { + // valid = false; + // } + // invalidFields = Object.assign({}, invalidFields, field); + // if (typeof callback === 'function' && ++count === this.fields.length) { + // callback(valid, invalidFields); + // } + // }); + // }); + // if (promise) { + // return promise; + // } }, scrollToField() {}, getFieldsValue(allFields) { - return allFields.map(({ prop, fieldValue }) => { - return { [prop]: fieldValue }; + const values = {}; + allFields.forEach(({ prop, fieldValue }) => { + values[prop] = fieldValue; }); + return values; }, validateFields() { - this.validateField(...arguments); + return this.validateField(...arguments); }, validateField(ns, opt, cb) { const pending = new Promise((resolve, reject) => { @@ -201,18 +205,18 @@ const Form = { return !!field.validateFirst; }); } - let invalidFields = {}; + let fieldsErrors = {}; let valid = true; let count = 0; fields.forEach(field => { - field.validate('', (message, field) => { - if (message) { + field.validate('', errors => { + if (errors) { valid = false; + fieldsErrors[field.prop] = errors; } - // TODO: - invalidFields = Object.assign({}, invalidFields, field); - if (typeof callback === 'function' && ++count === fields.length) { - callback(valid, invalidFields); + + if (++count === fields.length) { + callback(valid ? null : fieldsErrors, this.getFieldsValue(fields)); } }); }); diff --git a/components/form-model/FormItem.jsx b/components/form-model/FormItem.jsx index cf545c0c3..cd6fa7a4d 100644 --- a/components/form-model/FormItem.jsx +++ b/components/form-model/FormItem.jsx @@ -152,10 +152,10 @@ export default { } const model = {}; model[this.prop] = this.fieldValue; - validator.validate(model, { firstFields: true }, (errors, invalidFields) => { + validator.validate(model, {}, errors => { this.validateState = errors ? 'error' : 'success'; this.validateMessage = errors ? errors[0].message : ''; - callback(this.validateMessage, invalidFields); + callback(errors); this.FormContext && this.FormContext.$emit && this.FormContext.$emit('validate', this.prop, !errors, this.validateMessage || null); diff --git a/components/form-model/utils.js b/components/form-model/utils.js index f4e63fd01..9c95f47a6 100644 --- a/components/form-model/utils.js +++ b/components/form-model/utils.js @@ -59,3 +59,46 @@ export function hasRules(validate) { } return false; } + +export function computedStyle(el, prop) { + const getComputedStyle = window.getComputedStyle; + const style = + // If we have getComputedStyle + getComputedStyle + ? // Query it + // TODO: From CSS-Query notes, we might need (node, null) for FF + getComputedStyle(el) + : // Otherwise, we are in IE and use currentStyle + el.currentStyle; + if (style) { + return style[ + // Switch to camelCase for CSSOM + // DEV: Grabbed from jQuery + // https://github.com/jquery/jquery/blob/1.9-stable/src/css.js#L191-L194 + // https://github.com/jquery/jquery/blob/1.9-stable/src/core.js#L593-L597 + prop.replace(/-(\w)/gi, (word, letter) => { + return letter.toUpperCase(); + }) + ]; + } + return undefined; +} + +export function getScrollableContainer(n) { + let node = n; + let nodeName; + /* eslint no-cond-assign:0 */ + while ((nodeName = node.nodeName.toLowerCase()) !== 'body') { + const overflowY = computedStyle(node, 'overflowY'); + // https://stackoverflow.com/a/36900407/3040605 + if ( + node !== n && + (overflowY === 'auto' || overflowY === 'scroll') && + node.scrollHeight > node.clientHeight + ) { + return node; + } + node = node.parentNode; + } + return nodeName === 'body' ? node.ownerDocument : node; +} diff --git a/examples/App.vue b/examples/App.vue index 37487ed53..4c1512fb4 100644 --- a/examples/App.vue +++ b/examples/App.vue @@ -4,7 +4,7 @@