GenerateForm.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <template>
  2. <el-form
  3. ref="generateForm"
  4. label-suffix=":"
  5. :model="model"
  6. :rules="rules"
  7. :size="widgetForm.config.size"
  8. :label-position="widgetForm.config.labelPosition"
  9. :label-width="`${widgetForm.config.labelWidth}px`"
  10. :hide-required-asterisk="widgetForm.config.hideRequiredAsterisk"
  11. >
  12. <template v-for="(element, index) of widgetForm.list" :key="element.key">
  13. <GenerateFormItem
  14. :model="model"
  15. :updated-model="updatedModel"
  16. :element="widgetForm.list[index]"
  17. :config="data.config"
  18. :disabled="disabled"
  19. :request="request"
  20. />
  21. </template>
  22. </el-form>
  23. </template>
  24. <script lang="ts">
  25. import { defineComponent, reactive, toRefs, watch } from 'vue'
  26. import { ElMessage } from 'element-plus'
  27. import GenerateFormItem from './GenerateFormItem.vue'
  28. import { getWidgetForm } from '@/config'
  29. export default defineComponent({
  30. name: 'FormGenerate',
  31. components: {
  32. GenerateFormItem,
  33. },
  34. props: {
  35. data: {
  36. type: Object,
  37. default: getWidgetForm(),
  38. },
  39. value: {
  40. type: Object,
  41. },
  42. disabled: {
  43. type: Boolean,
  44. default: false,
  45. },
  46. request: {
  47. type: Function,
  48. },
  49. },
  50. setup(props) {
  51. const state = reactive({
  52. generateForm: null as any,
  53. model: {} as any,
  54. updatedModel: {} as any,
  55. rules: {} as any,
  56. widgetForm:
  57. (props.data && JSON.parse(JSON.stringify(props.data)))
  58. ?? getWidgetForm(),
  59. })
  60. const generateModel = (list: any[]) => {
  61. for (let index = 0; index < list.length; index++) {
  62. const model = list[index].model
  63. if (!model)
  64. return
  65. if (list[index].type === 'grid') {
  66. list[index].columns.forEach((col: any) => generateModel(col.list))
  67. }
  68. else {
  69. if (props.value && Object.keys(props.value).includes(model))
  70. state.model[model] = props.value[model]
  71. else
  72. state.model[model] = list[index].options.defaultValue
  73. state.rules[model] = list[index].options.rules
  74. }
  75. }
  76. }
  77. const generateOptions = (list: any[]) => {
  78. list.forEach(async(item) => {
  79. if (item.type === 'grid') {
  80. item.columns.forEach((col: any) => generateOptions(col.list))
  81. }
  82. else {
  83. if (item.options.remote && item.options.remoteFunc) {
  84. if (props.request) {
  85. const { data } = await props.request({
  86. url: item.options.remoteFunc,
  87. })
  88. item.options.remoteOptions = data.map((i: any) => ({
  89. label: i[item.options.props.label],
  90. value: i[item.options.props.value],
  91. children: i[item.options.props.children],
  92. }))
  93. return
  94. }
  95. fetch(item.options.remoteFunc)
  96. .then(resp => resp.json())
  97. .then((json) => {
  98. if (json instanceof Array) {
  99. item.options.remoteOptions = json.map(data => ({
  100. label: data[item.options.props.label],
  101. value: data[item.options.props.value],
  102. children: data[item.options.props.children],
  103. }))
  104. }
  105. })
  106. }
  107. }
  108. })
  109. }
  110. watch(
  111. () => props.data,
  112. (val) => {
  113. state.widgetForm
  114. = (val && JSON.parse(JSON.stringify(val))) ?? getWidgetForm()
  115. state.model = {}
  116. state.rules = {}
  117. generateModel(state.widgetForm.list)
  118. generateOptions(state.widgetForm.list)
  119. },
  120. { deep: true, immediate: true },
  121. )
  122. const getData = () => {
  123. return new Promise((resolve, reject) => {
  124. state.generateForm
  125. .validate()
  126. .then((validate: boolean) => {
  127. if (validate)
  128. resolve(state.updatedModel)
  129. else
  130. ElMessage.error('验证失败')
  131. })
  132. .catch((error: Error) => {
  133. reject(error)
  134. })
  135. })
  136. }
  137. const reset = () => {
  138. state.generateForm.resetFields()
  139. }
  140. return {
  141. ...toRefs(state),
  142. getData,
  143. reset,
  144. }
  145. },
  146. })
  147. </script>