UNPKG

yanzhen-design-vue

Version:

326 lines (325 loc) 10.3 kB
import { reactive, getCurrentInstance, provide, computed, isRef, onUnmounted, inject } from "vue"; import AUseForm from "ant-design-vue/es/form/useForm"; import { isNumeral, isEmptyArray, isEmptyValue } from "@yanzhen-libs/utils"; import { createWatcher, unref } from "@yanzhen-libs/utils-vue"; import { omit, pick, mergeWith, flattenDeep } from "lodash-es"; import { formContextIdKey, formContextKey } from "../constants.mjs"; function createReactiveMap(entries) { const map = reactive([]); function set(key, value) { for (const [, m] of Object.entries(map)) { if (key === m.key) { m.value = value; return m; } } map.push({ key, value }); } function get(key) { for (const [, { key: k, value }] of Object.entries(map)) { if (key === k) return value; } } function has(key) { for (const [, { key: k }] of Object.entries(map)) { if (key === k) return true; } } function deleteFn(key) { for (const [index, m] of Object.entries(map)) { if (m.key === key) { map.splice(Number(index), 1); return; } } } if (Array.isArray(entries)) { for (const [k, v] of entries) { set(k, v); } } const context = { set, get, has, delete: deleteFn, values() { return Object.entries(map).map(([, { value }]) => value); }, keys() { return Object.entries(map).map(([, { key }]) => key); } }; return new Proxy( map, { get(target, p, receiver) { switch (p) { case "length": return map.length; case "keys": return context.keys(); case "values": return context.values(); } if (typeof p === "string" && p in context) { return context[p]; } if (isNumeral(p)) { return map[Number(p)]; } return Reflect.get(target, p, receiver); } } ); } const useFormMap = /* @__PURE__ */ new WeakMap(); const handleOnValidates = (onValidates, ...args) => { for (const onValidate of onValidates) { if (typeof onValidate === "function") { onValidate(...args); } } }; const handleOnFieldChange = (onFieldChanges, ...args) => { for (const onFieldChange of onFieldChanges) { if (typeof onFieldChange === "function") { onFieldChange(...args); } } }; const methodsKey = ["clearValidate", "validate", "validateField", "resetFields"]; function useProvideForm(modelRef, rulesRef, options) { var _a; const keys = ["onValidateResult", "onFieldChange", "formRef"]; const options1 = omit(options ?? {}, ...keys); const options2 = pick(options ?? {}, ...keys, "onValidate"); const self = (_a = getCurrentInstance()) == null ? void 0 : _a.proxy; const watcher = createWatcher(); const config = useInjectForm(); function getOptionsFun(key) { const fun1 = config.parentPaths.map((form) => { var _a2; return (_a2 = useFormMap.get(form)) == null ? void 0 : _a2[key]; }); const fun2 = [...config.context.values()].map((form) => { var _a2; return (_a2 = useFormMap.get(form)) == null ? void 0 : _a2[key]; }); return [...fun1, ...fun2]; } const formInstance = AUseForm( modelRef ?? {}, rulesRef ?? {}, mergeWith({}, options1, { onValidate(...args) { var _a2; const validates = getOptionsFun("onValidate"); handleOnValidates(validates, unref(modelRef), ...args); (_a2 = options1 == null ? void 0 : options1.onValidate) == null ? void 0 : _a2.call(options1, ...args); } }) ); useFormMap.set(formInstance, options2); const contextKey = self ?? unref(config.id); if (modelRef) { config.set(contextKey, formInstance); provide( formContextIdKey, computed(() => contextKey) ); watcher.set("model", { source: () => unref(modelRef), handler(model) { const modelRef2 = formInstance.modelRef; if (isRef(modelRef2)) { modelRef2.value = model ?? {}; } else { mergeWith(modelRef2, model ?? {}); } }, immediate: true, debounce: 0 }); watcher.set("form.model", { source: () => unref(formInstance.modelRef), handler() { return; }, // immediate: true, deep: true, debounce: 500, onTrigger({ target, key }) { const rulesKeys = Object.keys(unref(formInstance.rulesRef)); const model = unref(formInstance.modelRef); if (model && Object.keys(model).includes(key)) { try { const value = target[key]; handleOnFieldChange(getOptionsFun("onFieldChange"), value, key, model); } catch { } if (rulesKeys.includes(key)) { } } } }); } if (rulesRef) { watcher.set("rules", { source: () => unref(rulesRef), handler(value) { formInstance.rulesRef.value = value; } }); } onUnmounted(() => { config.delete(contextKey); formInstance.resetFields(); provide( formContextIdKey, computed(() => unref(config.id)) ); watcher.stop(); }); provide(formContextKey, config); const scrollToField = (name, options3) => { var _a2; for (const value of [...config.context.values()]) { if (useFormMap.has(value)) { const { formRef } = useFormMap.get(value) ?? {}; const scrollToField2 = (_a2 = formRef == null ? void 0 : formRef.value) == null ? void 0 : _a2.scrollToField; if (typeof scrollToField2 === "function") { scrollToField2(name, options3); return; } } } }; const methods = pick(formInstance, ...methodsKey); const proxy = new Proxy(methods, { get(target, key, receiver) { if (typeof key === "string") { switch (key) { case "clearValidate": case "resetFields": case "validate": case "validateField": return async (...args) => { var _a2; const promise = []; const others = []; for (const value of [...config.context.values()]) { const fun = value[key]; if (useFormMap.has(value)) { others.push(useFormMap.get(value) ?? {}); } if (typeof fun === "function") { promise.push(fun(...args)); } } if (promise.length === 0) return; const results = await Promise.allSettled(promise); if (["validate", "validateField"].includes(key)) { const valids = []; for (const item of results) { if (item.status === "rejected") { if (key === "validate" && !isEmptyArray((_a2 = item == null ? void 0 : item.reason) == null ? void 0 : _a2.errorFields)) { valids.push(item.reason); } else if (key === "validateField" && !isEmptyArray(item == null ? void 0 : item.reason)) { const errors = flattenDeep( item.reason.map((valid) => valid.errors) ); if (!isEmptyArray(errors)) { valids.push(item.reason); } } } } for (const { onValidateResult } of others) { onValidateResult && onValidateResult(results); } return valids.length > 0 ? valids : void 0; } }; default: return formInstance[key]; } } return Reflect.get(target, key, receiver); } }); return { ...formInstance, proxy, scrollToField }; } function useInjectForm(key) { const map = /* @__PURE__ */ new Map(); const defaultContext = { context: map }; function toEmptyArray(arr, flatten = true) { if (flatten) arr = flattenDeep(arr); return arr.filter((value) => !isEmptyValue(value)); } const parentId = inject( formContextIdKey, computed(() => ({ uid: -1 })) ); const injectContext = inject(formContextKey, defaultContext); const config = new Proxy(injectContext, { get(target, p, receiver) { const context = injectContext.context; const [parent, ...parentPaths] = toEmptyArray( !isEmptyArray(injectContext == null ? void 0 : injectContext.parentPaths) ? injectContext.parentPaths : [], false ); switch (p) { case "id": return parentId; case "ctx": return context.get(unref(parentId)); case "set": return (key2, value) => { context == null ? void 0 : context.set(key2, value); (injectContext == null ? void 0 : injectContext.set) && injectContext.set(key2, value); }; case "get": return (key2) => { const values = (context == null ? void 0 : context.has(key2)) ? [context.get(key2)] : []; if (injectContext == null ? void 0 : injectContext.get) { const value = injectContext.get(key2); if (value) return values.concat(value); } return values; }; case "has": return context == null ? void 0 : context.has; case "delete": return (key2) => { context == null ? void 0 : context.delete(key2); (injectContext == null ? void 0 : injectContext.delete) && injectContext.delete(key2); }; case "root": return !isEmptyArray(parentPaths) ? parentPaths[parentPaths.length - 1] : parent; case "parentPaths": return !isEmptyArray(parentPaths) ? [parent].concat(parentPaths) : [parent]; case "parent": if (isEmptyValue(parent)) { return toEmptyArray([...context.values()]); } return toEmptyArray([parent]); } return Reflect.get(target, p, receiver); } }); if (key) { return computed(() => { return unref(config == null ? void 0 : config[key]); }); } return config; } export { useInjectForm, useProvideForm };