import { computed, getCurrentInstance, onMounted, ref } from 'vue' import { cloneDeep, get, set, merge } from 'lodash-es' import { FI } from '../types' import { randomCode, treeForEach } from 'utils' /* * formData * */ export function useFormData (props, emits) { const formData = computed({ get () { return props.modelValue }, set (val) { emits('update:modelValue', val) } }) function setFormData (value: any, key: any) { if (Array.isArray(key)) { key.forEach((item, index) => { if (value === '__DELETE__') { setValue(item, null) } else { setValue(item, value ? value[index] : null) } }) } else { setValue(key, value) } function setValue (key, val) { if (val === '__DELETE__') { const keys = key.split('.') const valueObj = get(formData.value, keys.slice(0, -1).join('.')) if (valueObj) { delete valueObj[keys[keys.length - 1]] } } else { set(formData.value, key, val) } } } function getFormData (key: any) { return get(formData.value, key) } return { formData, setFormData, getFormData } } /* * 获取循环的ref * */ export function useFormItemRefs () { const formItemRefs = ref({}) function setItemRefs (ref: any) { if (!ref) return if (ref.code) { formItemRefs.value[ref.code] = ref } if (ref.childrenRefs && Object.keys(ref.childrenRefs?.length > 0)) { Object.keys(ref.childrenRefs).map((key: string) => { setItemRefs(ref.childrenRefs[key]) }) } } return { formItemRefs, setItemRefs } } export function useMergeStyle (configOptions: any, style: any) { const instance: any = getCurrentInstance() const styled = computed(() => instance?.appContext.config.globalProperties.styled) const mergeStyle = computed(() => { return Object.assign({}, configOptions?.formItem?.style || {}, style || {}) }) return { mergeStyle, styled } } export function useFormItemProps (globalProps, itemProps) { return computed(() => { let ext = {} if (!itemProps.label && globalProps.value?.labelWidth) { ext = { labelWidth: '0' } } return Object.assign({}, globalProps.value, itemProps.props?.formItem, ext) }) } export function useItemHooks (props) { const modelData = ref({}) // 获取item项配置 function getItem (option: any) { if (typeof option !== 'number') { const { label, key, code } = option if (label) { return props.fields.find((f: any) => f.label === label) || {} } if (key) { return props.fields.find((f: any) => f.key === key) || {} } if (code) { return props.fields.find((f: any) => f.code === code) || {} } } else { return props.fields[option] } } // 获取item项对应值 function getItemValue (option: any) { if (typeof option !== 'number') { const { label, key, code } = option if (label) { const findItem = props.fields.find((f: any) => f.label === label) || {} return modelData.value[findItem?.code] } if (key) { const findItem = props.fields.find((f: any) => f.key === key) || {} return modelData.value[findItem?.code] } if (code) { return modelData.value[code] } } else { const findItem = props.fields[option] return modelData.value[findItem?.code] } } return { modelData, getItem, getItemValue } } /* * 设置initValue定义的初始值 * */ export function initValueHooks (formData, form, props, modelData) { const initKeys = ref([]) function setInitValue () { const valueObj: any = {} initKeys.value.map(item => { set(valueObj, item.key, item.value) if (item.code) { set(modelData.value, item.code, item.value) } }) formData.value = merge(props.modelValue, valueObj) } if (!form || form.length === 0) return form.forEach((item: FI) => { const initValue: any = item.initValue if (Array.isArray(item.key)) { let valArray: any = [] item.key.map((k, index) => { const keyValue = get(formData.value, k) if (!keyValue && keyValue !== 0 && initValue) { initKeys.value.push({ key: k, value: initValue[index] }) valArray = initValue } else { valArray.push(keyValue) } }) if (item.code) { set(modelData.value, item.code, valArray) } } else { const value = get(formData.value, item.key) if (!value && value !== 0 && (initValue || initValue === 0)) { initKeys.value.push({ key: item.key, code: item.code, value: initValue }) } else { if (item.code) { set(modelData.value, item.code, value) } } } }) setInitValue() return { initKeys } } /* * 设置initValue定义的初始值 * */ export function initValueGroupHooks (formData, form, props, modelData) { const initKeys = ref([]) function setInitValue () { const valueObj: any = {} initKeys.value.map(item => { set(valueObj, item.key, item.value) }) formData.value = Object.assign({}, props.modelValue, valueObj) } if (!form) return treeForEach(form, loopForm) function loopForm (item) { if (item.type === 'group') { let groupValue = get(props.modelValue, item.key, []) if (item.props.mode === 'array') { item.props.renderChildrenOrigin[0].map((child, cIndex) => { const childInitValue: any = child.initValue child.key = `${ item.key }[${ cIndex }]` const cValue = get(groupValue, cIndex) if (!cValue && childInitValue) { initKeys.value.push({ key: child.key, value: childInitValue }) set(modelData.value, child.code, childInitValue) } else { set(modelData.value, child.code, cValue) } }) } else { groupValue?.map((g, index) => { item.props.renderChildrenOrigin[index].map((child: any) => { const childInitValue: any = child.initValue || undefined const cValue = get(formData.value, child.key.replace('[i]', `[${ index }]`)) if (!cValue && childInitValue) { initKeys.value.push({ key: child.key.replace('[i]', `[${ index }]`), value: childInitValue }) set(modelData.value, child.code, childInitValue) } else { set(modelData.value, child.code, cValue) } }) }) } } } setInitValue() } export function useBuildForm (form) { /* * 获取所有slot插槽 * */ const slots = ref([]) /* * 去除code相同的slot * */ function filterSlots (slotsType: any[]) { const result: any = [] slotsType.forEach((item: any) => { if (result.findIndex((i: any) => i.code === item.code) === -1) { result.push(item) } }) return result } /* * 构建slots * */ function buildSlots (form) { const slotsType: any = [] if (!form) return form.forEach((item: any) => { if (item.type === 'slot') { slotsType.push({ label: item.label, code: item.code, slotName: item.slotName, key: item.key, rules: item.props?.rules, ...item }) } }) setTimeout(() => { slots.value = filterSlots([...slots.value, ...slotsType]) }, 0) } function buildUseForm (form) { if (!form) return form.forEach((item: FI) => { if (!item.code) { item.code = 'ele' + randomCode(18) } }) } buildUseForm(form) buildSlots(form) return { slots, buildUseForm } } export function useBuildGroupForm (form, formData) { /* * 获取所有slot插槽 * */ const slots = ref([]) /* * 去除code相同的slot * */ function filterSlots (slotsType: any[]) { const result: any = [] slotsType.forEach((item: any) => { if (result.findIndex((i: any) => i.code === item.code) === -1) { result.push(item) } }) return result } /* * 构建slots * */ function buildSlots (form) { const slotsType: any = [] if (!form) return form.forEach((item: any) => { if (item.type === 'slot') { slotsType.push({ label: item.label, code: item.code, key: item.key, rules: item.props?.rules, ...item }) } }) setTimeout(() => { slots.value = filterSlots([...slots.value, ...slotsType]) }, 0) } function buildUseForm (form, formData, parentKey?: string, mode = 'default') { if (!form) return form.forEach((item: any) => { if (!item.code) { item.code = 'ele' + randomCode(18) } if (item.type === 'group') { let groupValue = get(formData.value, item.key, []) if (!item.props.renderChildrenOrigin) item.props.renderChildrenOrigin = [] if (item.props.mode === 'array') { let children = [] if (!item.props.renderChildrenOrigin[0]) { children = cloneDeep(item.children) buildUseForm(children, item.key, 'array') item.props.renderChildrenOrigin[0] = children } } else { groupValue?.map((g, index) => { // children作为统一渲染 if (item.props.mode === 'default') { if (!item.props.renderChildrenOrigin[index]) { item.props.renderChildrenOrigin[index] = cloneDeep(item.children) buildUseForm(item.props.renderChildrenOrigin[index], formData, item.key) } } else { // 通过renderChildren渲染 if (!item.props.renderChildrenOrigin[index]) { item.props.renderChildrenOrigin[index] = item.props.renderChildren(index) buildUseForm(item.props.renderChildrenOrigin[index], formData, item.key) } } }) } } if (parentKey) { item.originKey = item.key if (mode === 'default') { item.key = parentKey + '[i].' + item.originKey } if (mode === 'array') { item.key = parentKey + '[i]' } } }) } buildUseForm(form, formData) buildSlots(form) return { slots, buildUseForm } }