@extclp/vexip-ui
Version:
A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good
1 lines • 8.16 kB
Source Map (JSON)
{"version":3,"file":"helper.mjs","sources":["../../../components/form/helper.ts"],"sourcesContent":["import { computed, getCurrentInstance, inject, onBeforeUnmount, provide } from 'vue'\n\nimport { isNull, noop, toFalse } from '@vexip-ui/utils'\nimport { FIELD_OPTIONS } from './symbol'\n\nimport type { ComputedRef } from 'vue'\nimport type { ComponentSize, ComponentState } from '@vexip-ui/config'\n\n/**\n * 根据路径读取对象中的值 (实现 ?. 的逻辑)\n *\n * @param obj 需要被读取的对象\n * @param path 读取的路径\n * @param strict 是否开启严格模式 (非法路径报错)\n */\nexport function getValueByPath<T = unknown>(\n obj: Record<string, any>,\n path: string | string[],\n strict = false\n): T | null {\n if (!obj || !path) return null\n\n if (typeof path === 'string') {\n if (path in obj) return obj[path]\n\n path = path.split('.')\n }\n\n if (Array.isArray(path) && path.length) {\n const lastKey = path.pop()\n\n if (!lastKey) return null\n\n for (let i = 0, len = path.length; i < len; ++i) {\n const key = String(path[i])\n\n if (!key) break\n\n obj = obj[key]\n\n if (isNull(obj)) {\n if (strict) {\n throw new Error('[vexip-ui:Form] Get value by an invalid path')\n }\n\n return obj\n }\n }\n\n if (strict && isNull(obj[lastKey])) {\n throw new Error('[vexip-ui:Form] Get value by an invalid path')\n }\n\n return obj[lastKey]\n }\n\n return null\n}\n\n/**\n * 根据路径设置对象中的值\n *\n * @param obj 需要被设置的对象\n * @param path 设置的路径\n * @param value 需要设置的值\n * @param strict 是否开启严格模式 (非法路径报错)\n */\nexport function setValueByPath(\n obj: Record<string, any>,\n path: string | string[],\n value: unknown,\n strict = false\n): boolean {\n if (!obj || !path) return false\n\n if (typeof path === 'string') {\n if (path in obj) {\n obj[path] = value\n\n return true\n }\n\n path = path.split('.')\n }\n\n if (Array.isArray(path) && path.length) {\n const lastKey = path.pop()\n\n if (!lastKey) return false\n\n for (let i = 0, len = path.length; i < len; ++i) {\n const key = String(path[i])\n\n if (!key) {\n return false\n }\n\n if (typeof obj[key] !== 'object') {\n if (strict) {\n throw new Error('[vexip-ui:Form] Set value by an invalid path')\n }\n\n obj[key] = {}\n }\n\n obj = obj[key]\n }\n\n if (strict && typeof obj !== 'object') {\n throw new Error('[vexip-ui:Form] Set value by an invalid path')\n }\n\n obj[lastKey] = value\n\n return true\n }\n\n return false\n}\n\nexport interface FormFieldStore<V = unknown> {\n isField: boolean,\n idFor: ComputedRef<string | undefined>,\n labelId: ComputedRef<string | undefined>,\n state: ComputedRef<ComponentState>,\n disabled: ComputedRef<boolean>,\n loading: ComputedRef<boolean>,\n size: ComputedRef<ComponentSize>,\n validateField: () => Promise<string[] | null>,\n clearField: (defaultValue?: V) => void,\n resetField: () => boolean,\n getFieldValue: (defaultValue?: V) => V,\n setFieldValue: (value: V, strict?: boolean) => void\n}\n\nconst defaultId = computed(() => undefined as string | undefined)\nconst defaultState = computed(() => 'default' as ComponentState)\nconst defaultFalse = computed(() => false)\nconst defaultSize = computed(() => 'default' as ComponentSize)\n\nfunction getEmptyActions<V>() {\n return {\n isField: false,\n idFor: defaultId,\n labelId: defaultId,\n state: defaultState,\n disabled: defaultFalse,\n loading: defaultFalse,\n size: defaultSize,\n validateField: noop,\n clearField: noop,\n resetField: toFalse,\n getFieldValue: v => v,\n setFieldValue: noop\n } as FormFieldStore<V>\n}\n\n/**\n * Create a field store, provide field states and control methods\n *\n * @param onFocus a focus method for focusing when label is clicked\n */\nexport function useFieldStore<V = unknown>(onFocus?: () => void): FormFieldStore<V> {\n const instance = getCurrentInstance()\n\n if (!instance) return getEmptyActions<V>()\n\n const fieldOptions = inject(FIELD_OPTIONS, null)\n\n if (!fieldOptions) {\n return getEmptyActions<V>()\n }\n\n // Block the provided if there are dependencies between control components.\n // e.g. AutoComplete -> Select, ColorPicker -> Input\n provide(FIELD_OPTIONS, null!)\n fieldOptions.sync(instance)\n onFocus && fieldOptions.emitter.on('focus', onFocus)\n\n onBeforeUnmount(() => {\n fieldOptions.unSync(instance)\n onFocus && fieldOptions.emitter.off('focus', onFocus)\n })\n\n function clearField(defaultValue?: V) {\n if (!fieldOptions) return\n\n fieldOptions.setValue(defaultValue)\n fieldOptions.clearError()\n }\n\n return {\n isField: true,\n idFor: fieldOptions.idFor,\n labelId: fieldOptions.labelId,\n state: fieldOptions.state,\n disabled: fieldOptions.disabled,\n loading: fieldOptions.loading,\n size: fieldOptions.size,\n validateField: fieldOptions.validate,\n clearField,\n resetField: fieldOptions.reset,\n getFieldValue: fieldOptions.getValue as (defaultValue?: V) => V,\n setFieldValue: fieldOptions.setValue as (value: V, strict?: boolean) => void\n }\n}\n"],"names":["getValueByPath","obj","path","strict","lastKey","i","len","key","isNull","setValueByPath","value","defaultId","computed","defaultState","defaultFalse","defaultSize","getEmptyActions","noop","toFalse","v","useFieldStore","onFocus","instance","getCurrentInstance","fieldOptions","inject","FIELD_OPTIONS","provide","onBeforeUnmount","clearField","defaultValue"],"mappings":"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"}