UNPKG

d-render

Version:

数据渲染库 - form、table、search-form

169 lines (155 loc) 5.37 kB
import { unref, Ref } from 'vue' import { getFieldValue, isNotEmpty, setFieldValue, cloneDeep, IAnyObject, IRenderConfig, IRenderConfigDependOn, TFormConfig } from '@d-render/shared' interface IEffectFunc { value: (...args: Array<unknown>) => unknown | Promise<unknown> } interface IEffect{ [key: string]: string | IEffectFunc } export type IObjectKey = IRenderConfigDependOn export type IKey = IObjectKey | string export const getValuesByKeys = (data: IAnyObject = {}, keys:Array<IKey> = []) => { const result = {} keys.forEach((key) => { if (typeof key === 'object') { const object = key setFieldValue(result, object.key, getFieldValue(data, object.key), true) } else { setFieldValue(result, key, getFieldValue(data, key), true) } }) return result } export const setValuesByKeys = (target:IAnyObject = {}, keys:Array<IKey> = [], values: IAnyObject = {}) => { keys.forEach((key) => { if (typeof key === 'object') { const object = key setFieldValue(target, object.key, getFieldValue(values, object.key), true) } else { setFieldValue(target, key, getFieldValue(values, key), true) } }) } // 去除对象的指定属性后返回去除属性的集合仅适用于单层对象 const filterProperty = (object: IAnyObject, properties: Array<string>) => { // 进行一次浅拷贝防止deleteProperty删除修改原始对象 const newObject = { ...object } const omitObject = properties.reduce((acc: Record<string, unknown>, key) => { const v = object[key] Reflect.deleteProperty(object, key) acc[key] = v return acc }, {}) return [newObject, omitObject] } // 深克隆非指定属性 export const cloneDeepConfig = (config: TFormConfig) => { // const fixedKeys = ['dependOn', 'changeConfig', 'changeValue', 'changeValueByOld', 'outDependOn', 'asyncOptions', '$render'] // const [volatileConfig, fixedConfig] = filterProperty(config, fixedKeys) // const newConfig = return cloneDeep(config) } export const isHideLabel = (config: TFormConfig) => { return ( config.hideLabel || (isNotEmpty(config.labelWidth) && !config.labelWidth) || !config.label ) } export const getLabelWidth = (config: TFormConfig) => { if (config.hideLabel) return '0px' if (isNotEmpty(config.labelWidth)) { if (isNaN(config.labelWidth as unknown as number)) return config.labelWidth as string return config.labelWidth + 'px' } if (!config.label) return '0px' // 兼容老的设计 return undefined } export const getChangeIndex = (values: Array<unknown>, oldValues: Array<unknown>) => { const result: Array<number> = [] values.forEach((v, i) => { if (typeof v === 'object') { // 数组 对象相等判断 // 无法通过值来判断对象级数组是否变化 (地址引用导致2个值一直都是相等的) result.push(i) } else { if (v !== oldValues[i]) { result.push(i) } } }) return result } export const secureNewFn = (...params: Array<string>) => { const funcBody = params.pop() try { // eslint-disable-next-line no-new-func return new Function(...params, funcBody as string) } catch (error) { console.error(error) return () => {} } } export const judgeUseFn = (key: string, config: IRenderConfig, effect: IEffect) => { // console.log(key, config, effect); // eslint-disable-next-line no-new-func if (key === 'changeValue' && config.changeValueStr) { return secureNewFn( 'dependOnValues', 'outDependOnValues', config.changeValueStr ) } if (key === 'changeConfig' && config.changeConfigStr) { return secureNewFn( 'config', 'dependOnValues', 'outDependOnValues', config.changeConfigStr ) } // 对asyncOptions的特殊处理 // @ts-ignore if (key === 'asyncOptions' && typeof config.asyncOptions === 'string') { return secureNewFn('dependOnValues', 'outDependOnValues', config.asyncOptions) } if (!effect) return config[key] // 没有effect 参数则直接使用config[key] if (effect && key in effect) { // 有effect 且 effect对象明确存在key(不管其值为什么) if (typeof effect[key] === 'function') return effect[key] // effect中的值为函数 则认为此次响应使用局部方法 return config[key] } } export class UpdateModelQueue { getModel: () => IAnyObject | Ref<IAnyObject> updateModel: (value: IAnyObject) => void data: Map<string, unknown> = new Map() isCollect?: boolean constructor (getModel: () => IAnyObject | Ref<IAnyObject>, updateModel: (value: IAnyObject) => void) { this.getModel = getModel this.updateModel = updateModel } init () { this.data = new Map() } append (key: string, value: unknown) { if (!this.isCollect) { this.init() this.isCollect = true // setTimeout(() => { // }, 20) } this.data?.set(key, value) // = value this.update() // 直接触发 // setFieldValue(this.data, key, value) } update () { const model = unref(this.getModel()) // 维持model是最新的 // eslint-disable-next-line no-unused-vars for (const key of this.data.keys()) { const value = this.data.get(key) setFieldValue(model, key, value, true) } this.isCollect = false this.updateModel(model) this.init() // 清空原来的数据 } }