import { computed, ref, watch, unref } from 'vue' import { useElFormItemInject } from './use-form' import { isEmpty, isNotEmpty, getLabelByValue, isObject, isArray, isNumber, getFieldValue, setFieldValue } from '@cip/utils/util' import { getValueByTemplate } from '@cip/components/cip-form-input/form-value-store' const useProxyOtherValue = (props, emitOtherValue) => { const result = [] if (props.config.otherKey) { const isStringKey = typeof props.config.otherKey === 'string' const otherKey = isStringKey ? [props.config.otherKey] : props.config.otherKey otherKey.forEach(key => { const proxyValue = computed({ get () { return isStringKey ? props.otherValue : getFieldValue(props.otherValue, key) }, set (val) { if (isStringKey) { emitOtherValue(val) } else { const otherValue = props.otherValue setFieldValue(otherValue, key, val) emitOtherValue(otherValue) } } }) result.push(proxyValue) }) } return result } const useFormBasicConfig = (props) => { const securityConfig = computed(() => { return props.config ?? {} }) const clearable = computed(() => { return securityConfig.value.clearable ?? true }) const width = computed(() => { return securityConfig.value.width ?? '100%' }) const placeholder = computed(() => { return securityConfig.value.placeholder ?? ' ' }) return { securityConfig, clearable, width, placeholder } } export const useFormInput = (props, context) => { const inputRef = ref() const { securityConfig, clearable, width, placeholder } = useFormBasicConfig(props) const emitInput = (val) => { context.emit('update:modelValue', val) } const emitModelValue = (val) => { emitInput(val) } const emitOtherValue = (val) => { context.emit('update:otherValue', val) } const proxyOtherValue = useProxyOtherValue(props, emitOtherValue) watch(() => securityConfig.value.defaultValue, (defaultValue) => { if (props.showTemplate === true) { // 处于展示模版模式时,同步展示默认值【注:此模式仅在设计表单时开启】 emitInput(defaultValue) } else { // 处于实际值展示模式时, 需要modelValue 和defaultValue都不为空才进行值的更新 if (isEmpty(props.modelValue) && isNotEmpty(defaultValue)) { emitInput(getValueByTemplate(defaultValue)) } } }, { immediate: true }) const proxyValue = computed({ // 单值时使用 get () { return props.modelValue }, set (val) { emitModelValue(val) } }) return { inputRef, proxyValue, securityConfig, emitInput, emitModelValue, emitOtherValue, proxyOtherValue, placeholder, clearable, width } } export const useFormView = (props) => { const { securityConfig, clearable, width, placeholder } = useFormBasicConfig(props) const proxyOtherValue = useProxyOtherValue(props, () => {}) return { securityConfig, clearable, width, placeholder, proxyOtherValue } } export const useElementFormEvent = () => { const elFormItem = useElFormItemInject() const handleChange = (val) => { elFormItem.formItemMitt?.emit('el.form.change', [val]) } const handleBlur = (val) => { console.log(elFormItem, val) elFormItem.formItemMitt?.emit('el.form.blur', [val]) } return { handleChange, handleBlur } } export const useOptions = (props, multiple, emitInput, emitOtherValue) => { const optionProps = computed(() => { const { label = 'label', value = 'value', children = 'children' } = props.config?.optionProps ?? {} return { label, value, children } }) const splitKey = computed(() => { return props.config?.splitKey ?? ',' }) const withObject = computed(() => { // 传出的值是否为object return props.config?.withObject ?? false }) const realArray = computed(() => { // 需要返回的shu return props.config?.realArray ?? false }) const options = ref([]) const getOptions = async (val, outVal) => { if (props.config.asyncOptions) { options.value = await props.config.asyncOptions(val, outVal) } else { options.value = props.config?.options ?? [] } if (isEmpty(props.modelValue) && props.config.autoSelect && emitInput) { // modelValue为空 const autoValue = isObjectOption.value ? options.value[0][optionProps.value.value] : options.value[0] const autoLabel = isObjectOption.value ? options.value[0][optionProps.value.label] : options.value[0] // eslint-disable-next-line no-unused-expressions emitInput(autoValue) emitOtherValue && emitOtherValue(autoLabel) } } // 计算option类型 const isObjectOption = computed(() => { return isObject(options.value[0]) }) // 获取otherValue的值 const getOtherValueByValue = (value) => { if (unref(multiple)) { if (withObject.value) { return value.map(i => { return options.value?.find(v => v[optionProps.value.value] === i) ?? {} }) } return value.map(val => getLabelByValue(val, options.value, optionProps.value) ?? val).join(splitKey.value) } else { if (withObject.value) { return options.value?.find(v => v[optionProps.value.value] === value) ?? {} } return getLabelByValue(value, options.value, optionProps.value) ?? value } } const getValue = (modelValue) => { if (unref(multiple)) { // 防止空字符串导致的['']错误 const modelArray = isArray(modelValue) ? modelValue : (modelValue ? modelValue.split(splitKey.value) : []) // 如果option的value值是数字型将值转换为数字型,否则就是字符型 const optionCell = isObjectOption.value ? options.value[0]?.[optionProps.value.value] : options.value[0] if (isNumber(optionCell)) { return modelArray.map(i => parseInt(i)) } else { return modelArray.map(i => String(i)) } } else { return modelValue ?? '' } } const getModelValue = (value) => { if (unref(multiple)) { if (realArray.value) { return value } else { return isArray(value) ? value.join(splitKey.value) : value } } else { return value } } // 根据otherValue跟随modelValue变化 const getOtherValue = (modelValue, value) => { if (isObjectOption.value) { return getOtherValueByValue(value) } else { return modelValue } } if (!(props.config.dependOn?.length) && !(props.config.outDependOn?.length)) { getOptions() // .then(() => { console.log('[init]: getOptions') }) if (props.config.options) { // 动态表单设计时修改options需要触发此方法 watch(() => props.config.options, (val) => { getOptions() // .then(() => { console.log('[config.options change]: getOptions') }) }) } } else { watch([() => props.dependOnValues, () => props.outDependOnValues], ([dependOnValues, outDependOnValues]) => { getOptions(dependOnValues || {}, outDependOnValues || {}) // .then(() => { console.log('[dependOn change]: getOptions') }) }, { immediate: true }) } return { optionProps, options, getOptions, isObjectOption, getValue, getModelValue, getOtherValue } }