form-input.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import { computed, ref, watch, unref } from 'vue'
  2. import { useElFormItemInject } from './use-form'
  3. import {
  4. isEmpty,
  5. isNotEmpty,
  6. getLabelByValue,
  7. isObject,
  8. isArray,
  9. isNumber,
  10. getFieldValue,
  11. setFieldValue
  12. } from '@cip/utils/util'
  13. import { getValueByTemplate } from '@cip/components/cip-form-input/form-value-store'
  14. const useProxyOtherValue = (props, emitOtherValue) => {
  15. const result = []
  16. if (props.config.otherKey) {
  17. const isStringKey = typeof props.config.otherKey === 'string'
  18. const otherKey = isStringKey ? [props.config.otherKey] : props.config.otherKey
  19. otherKey.forEach(key => {
  20. const proxyValue = computed({
  21. get () {
  22. return isStringKey ? props.otherValue : getFieldValue(props.otherValue, key)
  23. },
  24. set (val) {
  25. if (isStringKey) {
  26. emitOtherValue(val)
  27. } else {
  28. const otherValue = props.otherValue
  29. setFieldValue(otherValue, key, val)
  30. emitOtherValue(otherValue)
  31. }
  32. }
  33. })
  34. result.push(proxyValue)
  35. })
  36. }
  37. return result
  38. }
  39. const useFormBasicConfig = (props) => {
  40. const securityConfig = computed(() => {
  41. return props.config ?? {}
  42. })
  43. const clearable = computed(() => {
  44. return securityConfig.value.clearable ?? true
  45. })
  46. const width = computed(() => {
  47. return securityConfig.value.width ?? '100%'
  48. })
  49. const placeholder = computed(() => {
  50. return securityConfig.value.placeholder ?? ' '
  51. })
  52. return {
  53. securityConfig, clearable, width, placeholder
  54. }
  55. }
  56. export const useFormInput = (props, context) => {
  57. const inputRef = ref()
  58. const { securityConfig, clearable, width, placeholder } = useFormBasicConfig(props)
  59. const emitInput = (val) => {
  60. context.emit('update:modelValue', val)
  61. }
  62. const emitModelValue = (val) => {
  63. emitInput(val)
  64. }
  65. const emitOtherValue = (val) => {
  66. context.emit('update:otherValue', val)
  67. }
  68. const proxyOtherValue = useProxyOtherValue(props, emitOtherValue)
  69. watch(() => securityConfig.value.defaultValue, (defaultValue) => {
  70. if (props.showTemplate === true) {
  71. // 处于展示模版模式时,同步展示默认值【注:此模式仅在设计表单时开启】
  72. emitInput(defaultValue)
  73. } else {
  74. // 处于实际值展示模式时, 需要modelValue 和defaultValue都不为空才进行值的更新
  75. if (isEmpty(props.modelValue) && isNotEmpty(defaultValue)) {
  76. emitInput(getValueByTemplate(defaultValue))
  77. }
  78. }
  79. }, { immediate: true })
  80. const proxyValue = computed({
  81. // 单值时使用
  82. get () {
  83. return props.modelValue
  84. },
  85. set (val) {
  86. emitModelValue(val)
  87. }
  88. })
  89. return {
  90. inputRef,
  91. proxyValue,
  92. securityConfig,
  93. emitInput,
  94. emitModelValue,
  95. emitOtherValue,
  96. proxyOtherValue,
  97. placeholder,
  98. clearable,
  99. width
  100. }
  101. }
  102. export const useFormView = (props) => {
  103. const { securityConfig, clearable, width, placeholder } = useFormBasicConfig(props)
  104. const proxyOtherValue = useProxyOtherValue(props, () => {})
  105. return {
  106. securityConfig, clearable, width, placeholder, proxyOtherValue
  107. }
  108. }
  109. export const useElementFormEvent = () => {
  110. const elFormItem = useElFormItemInject()
  111. const handleChange = (val) => {
  112. elFormItem.formItemMitt?.emit('el.form.change', [val])
  113. }
  114. const handleBlur = (val) => {
  115. console.log(elFormItem, val)
  116. elFormItem.formItemMitt?.emit('el.form.blur', [val])
  117. }
  118. return {
  119. handleChange,
  120. handleBlur
  121. }
  122. }
  123. export const useOptions = (props, multiple, emitInput, emitOtherValue) => {
  124. const optionProps = computed(() => {
  125. const { label = 'label', value = 'value', children = 'children' } = props.config?.optionProps ?? {}
  126. return { label, value, children }
  127. })
  128. const splitKey = computed(() => {
  129. return props.config?.splitKey ?? ','
  130. })
  131. const withObject = computed(() => {
  132. // 传出的值是否为object
  133. return props.config?.withObject ?? false
  134. })
  135. const realArray = computed(() => {
  136. // 需要返回的shu
  137. return props.config?.realArray ?? false
  138. })
  139. const options = ref([])
  140. const getOptions = async (val, outVal) => {
  141. if (props.config.asyncOptions) {
  142. options.value = await props.config.asyncOptions(val, outVal)
  143. } else {
  144. options.value = props.config?.options ?? []
  145. }
  146. if (isEmpty(props.modelValue) && props.config.autoSelect && emitInput) { // modelValue为空
  147. const autoValue = isObjectOption.value ? options.value[0][optionProps.value.value] : options.value[0]
  148. const autoLabel = isObjectOption.value ? options.value[0][optionProps.value.label] : options.value[0]
  149. // eslint-disable-next-line no-unused-expressions
  150. emitInput(autoValue)
  151. emitOtherValue && emitOtherValue(autoLabel)
  152. }
  153. }
  154. // 计算option类型
  155. const isObjectOption = computed(() => {
  156. return isObject(options.value[0])
  157. })
  158. // 获取otherValue的值
  159. const getOtherValueByValue = (value) => {
  160. if (unref(multiple)) {
  161. if (withObject.value) {
  162. return value.map(i => {
  163. return options.value?.find(v => v[optionProps.value.value] === i) ?? {}
  164. })
  165. }
  166. return value.map(val => getLabelByValue(val, options.value, optionProps.value) ?? val).join(splitKey.value)
  167. } else {
  168. if (withObject.value) {
  169. return options.value?.find(v => v[optionProps.value.value] === value) ?? {}
  170. }
  171. return getLabelByValue(value, options.value, optionProps.value) ?? value
  172. }
  173. }
  174. const getValue = (modelValue) => {
  175. if (unref(multiple)) {
  176. // 防止空字符串导致的['']错误
  177. const modelArray = isArray(modelValue) ? modelValue : (modelValue ? modelValue.split(splitKey.value) : [])
  178. // 如果option的value值是数字型将值转换为数字型,否则就是字符型
  179. const optionCell = isObjectOption.value ? options.value[0]?.[optionProps.value.value] : options.value[0]
  180. if (isNumber(optionCell)) {
  181. return modelArray.map(i => parseInt(i))
  182. } else {
  183. return modelArray.map(i => String(i))
  184. }
  185. } else {
  186. return modelValue ?? ''
  187. }
  188. }
  189. const getModelValue = (value) => {
  190. if (unref(multiple)) {
  191. if (realArray.value) {
  192. return value
  193. } else {
  194. return isArray(value) ? value.join(splitKey.value) : value
  195. }
  196. } else {
  197. return value
  198. }
  199. }
  200. // 根据otherValue跟随modelValue变化
  201. const getOtherValue = (modelValue, value) => {
  202. if (isObjectOption.value) {
  203. return getOtherValueByValue(value)
  204. } else {
  205. return modelValue
  206. }
  207. }
  208. if (!(props.config.dependOn?.length) && !(props.config.outDependOn?.length)) {
  209. getOptions() // .then(() => { console.log('[init]: getOptions') })
  210. if (props.config.options) { // 动态表单设计时修改options需要触发此方法
  211. watch(() => props.config.options, (val) => {
  212. getOptions() // .then(() => { console.log('[config.options change]: getOptions') })
  213. })
  214. }
  215. } else {
  216. watch([() => props.dependOnValues, () => props.outDependOnValues], ([dependOnValues, outDependOnValues]) => {
  217. getOptions(dependOnValues || {}, outDependOnValues || {}) // .then(() => { console.log('[dependOn change]: getOptions') })
  218. }, { immediate: true })
  219. }
  220. return {
  221. optionProps,
  222. options,
  223. getOptions,
  224. isObjectOption,
  225. getValue,
  226. getModelValue,
  227. getOtherValue
  228. }
  229. }