UNPKG

@ant-design-vue/use

Version:

Vue 3 Composition Api Library.

299 lines (250 loc) 9.06 kB
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } import { reactive, watch, nextTick } from 'vue'; import cloneDeep from 'lodash-es/cloneDeep'; import intersection from 'lodash-es/intersection'; import isEqual from 'lodash-es/isEqual'; import debounce from 'lodash-es/debounce'; import omit from 'lodash-es/omit'; import { validateRules } from 'ant-design-vue/es/form/utils/validateUtil'; import { defaultValidateMessages } from 'ant-design-vue/es/form/utils/messages'; import { allPromiseFinish } from 'ant-design-vue/es/form/utils/asyncUtil'; import { tuple } from 'ant-design-vue/es/_util/type'; function isRequired(rules) { var isRequired = false; if (rules && rules.length) { rules.every(function (rule) { if (rule.required) { isRequired = true; return false; } return true; }); } return isRequired; } function toArray(value) { if (value === undefined || value === null) { return []; } return Array.isArray(value) ? value : [value]; } var validateStatus = tuple('', 'success', 'warning', 'error', 'validating'); function getPropByPath(obj, path, strict) { var tempObj = obj; path = path.replace(/\[(\w+)\]/g, '.$1'); path = path.replace(/^\./, ''); var keyArr = path.split('.'); var i = 0; for (var len = keyArr.length; i < len - 1; ++i) { if (!tempObj && !strict) break; var key = keyArr[i]; if (key in tempObj) { tempObj = tempObj[key]; } else { if (strict) { throw new Error('please transfer a valid name path to validate!'); } break; } } return { o: tempObj, k: keyArr[i], v: tempObj ? tempObj[keyArr[i]] : null, isValid: tempObj && keyArr[i] in tempObj }; } function useForm(modelRef, rulesRef, options) { var initialModel = cloneDeep(modelRef); var validateInfos = {}; Object.keys(rulesRef).forEach(function (key) { validateInfos[key] = { autoLink: false, required: isRequired(rulesRef[key]) }; }); validateInfos = reactive(validateInfos); var resetFields = function resetFields(newValues) { _extends(modelRef, _objectSpread({}, cloneDeep(initialModel), newValues)); //modelRef = resetReactiveValue(initialModel, modelRef); nextTick(function () { Object.keys(validateInfos).forEach(function (key) { validateInfos[key] = { autoLink: false, required: isRequired(rulesRef[key]) }; }); }); }; var filterRules = function filterRules() { var rules = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var trigger = arguments.length > 1 ? arguments[1] : undefined; if (!trigger.length) { return rules; } else { return rules.filter(function (rule) { var triggerList = toArray(rule.trigger || 'change'); return intersection(triggerList, trigger).length; }); } }; var lastValidatePromise = null; var validateFields = function validateFields(names) { var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var strict = arguments.length > 2 ? arguments[2] : undefined; var promiseList = []; var values = {}; var _loop = function _loop(i) { var name = names[i]; var prop = getPropByPath(modelRef, name, strict); if (!prop.isValid) return "continue"; values[name] = prop.v; var rules = filterRules(rulesRef[name], toArray(option && option.trigger)); if (rules.length) { promiseList.push(validateField(name, prop.v, rules, option || {}).then(function () { return { name: name, errors: [] }; })["catch"](function (errors) { return Promise.reject({ name: name, errors: errors }); })); } }; for (var i = 0; i < names.length; i++) { var _ret = _loop(i); if (_ret === "continue") continue; } var summaryPromise = allPromiseFinish(promiseList); lastValidatePromise = summaryPromise; var returnPromise = summaryPromise.then(function () { if (lastValidatePromise === summaryPromise) { return Promise.resolve(values); } return Promise.reject([]); })["catch"](function (results) { var errorList = results.filter(function (result) { return result && result.errors.length; }); return Promise.reject({ values: values, errorFields: errorList, outOfDate: lastValidatePromise !== summaryPromise }); }); // Do not throw in console returnPromise["catch"](function (e) { return e; }); return returnPromise; }; var validateField = function validateField(name, value, rules, option) { var promise = validateRules([name], value, rules, _objectSpread({ validateMessages: defaultValidateMessages }, option), !!option.validateFirst); validateInfos[name].validateStatus = 'validating'; promise["catch"](function (e) { return e; }).then(function () { var errors = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; if (validateInfos[name].validateStatus === 'validating') { validateInfos[name].validateStatus = errors.length ? 'error' : 'success'; validateInfos[name].help = errors[0]; } }); return promise; }; var validate = function validate(names, option) { var keys = []; var strict = true; if (!names) { strict = false; keys = Object.keys(rulesRef); } else if (Array.isArray(names)) { keys = names; } else { keys = [names]; } var promises = validateFields(keys, option || {}, strict); // Do not throw in console promises["catch"](function (e) { return e; }); return promises; }; var clearValidate = function clearValidate(names) { var keys = []; if (!names) { keys = Object.keys(rulesRef); } else if (Array.isArray(names)) { keys = names; } else { keys = [names]; } keys.forEach(function (key) { validateInfos[key] && _extends(validateInfos[key], { validateStatus: '', help: '' }); }); }; var mergeValidateInfo = function mergeValidateInfo() { var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var info = { autoLink: false }; var help = []; var infos = Array.isArray(items) ? items : [items]; for (var i = 0; i < infos.length; i++) { var arg = infos[i]; if ((arg === null || arg === void 0 ? void 0 : arg.validateStatus) === 'error') { info.validateStatus = 'error'; arg.help && help.push(arg.help); } info.required = info.required || (arg === null || arg === void 0 ? void 0 : arg.required); } info.help = help.join('\n'); return info; }; var oldModel = initialModel; var modelFn = function modelFn(model) { var names = []; Object.keys(rulesRef).forEach(function (key) { var prop = getPropByPath(model, key, false); var oldProp = getPropByPath(oldModel, key, false); if (!isEqual(prop.v, oldProp.v)) { names.push(key); } }); validate(names, { trigger: 'change' }); oldModel = cloneDeep(model); }; var debounceOptions = options === null || options === void 0 ? void 0 : options.debounce; watch(modelRef, debounceOptions && debounceOptions.wait ? debounce(modelFn, debounceOptions.wait, omit(debounceOptions, ['wait'])) : modelFn, { immediate: options && !!options.immediate, deep: true }); watch(rulesRef, function () { if (options && options.validateOnRuleChange) { validate(); } }, { deep: true }); return { modelRef: modelRef, rulesRef: rulesRef, initialModel: initialModel, validateInfos: validateInfos, resetFields: resetFields, validate: validate, validateField: validateField, mergeValidateInfo: mergeValidateInfo, clearValidate: clearValidate }; } export default useForm;