index.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <template>
  2. <v-form ref="formRef" v-model="valid" class="login-form" @submit.prevent>
  3. <div>
  4. <v-row dense no-gutters class="justify-space-between">
  5. <template v-for="(item) in props.items.options">
  6. <slot :name="item.prevSlot"></slot>
  7. <v-col :key="item.key" v-if="!item.hide" :cols="item.col || '12'" class="position">
  8. <template v-if="item.slotTitle">
  9. <div :class="item.class" :style="item.slotTitleStyle">{{ item.slotTitle }}</div>
  10. </template>
  11. <div class="d-flex mb-2" :class="item.flexStyle || 'flex-row'">
  12. <!-- <span>{{ item.value }}</span> -->
  13. <textUI
  14. v-if="['text', 'password', 'number', 'phoneNumber'].includes(item.type)"
  15. v-model="item.value"
  16. :item="item"
  17. @blur="item.blur"
  18. @change="handleChange(item)"
  19. ></textUI>
  20. <autocompleteUI
  21. v-if="item.type === 'autocomplete'"
  22. v-model="item.value"
  23. :item="item"
  24. @search="v => item.search ? item.search(v) : null"
  25. @change="handleChange(item)"
  26. ></autocompleteUI>
  27. <comboboxUI
  28. v-if="item.type === 'combobox'"
  29. v-model="item.value"
  30. :item="item"
  31. @search="v => item.search ? item.search(v) : null"
  32. @change="handleChange(item)"
  33. ></comboboxUI>
  34. <!-- comboboxZhAndEnUI暂不可用 -->
  35. <!-- <comboboxZhAndEnUI
  36. v-if="item.type === 'comboboxZhAndEn'"
  37. v-model="item.value"
  38. :item="item"
  39. @search="v => item.search ? item.search(v) : null"
  40. @change="handleChange(item)"
  41. ></comboboxZhAndEnUI> -->
  42. <radioGroupUI
  43. v-if="item.type === 'ifRadio'"
  44. v-model="item.value"
  45. :item="item"
  46. @change="handleChange(item)"
  47. ></radioGroupUI>
  48. <checkboxUI
  49. v-if="item.type === 'checkbox'"
  50. v-model="item.value"
  51. :item="item"
  52. @change="handleChange(item)"
  53. ></checkboxUI>
  54. <textareaUI
  55. v-if="item.type === 'textarea'"
  56. v-model="item.value"
  57. :item="item"
  58. @change="handleChange(item)"
  59. ></textareaUI>
  60. <cascadeUI
  61. v-if="item.type === 'cascade'"
  62. v-model="item.value"
  63. :item="item"
  64. @change="handleChange(item)"
  65. ></cascadeUI>
  66. <nestedListGroupUI
  67. v-if="item.type === 'nestedListGroup'"
  68. v-model="item.value"
  69. :item="item"
  70. @change="handleChange(item)"
  71. ></nestedListGroupUI>
  72. <datePickerUI
  73. v-if="item.type === 'datePicker'"
  74. v-model="item.value"
  75. :item="item"
  76. @change="handleChange(item)"
  77. ></datePickerUI>
  78. <DatePicker v-if="item.type === 'vueDatePicker'" v-model="item.value" :options="item.options" :width="item.width" :class="item.class"></DatePicker>
  79. <v-file-input
  80. v-if="item.type === 'upload'"
  81. :prepend-icon="item.prependIcon || ''"
  82. :append-icon="item.appendIcon"
  83. :append-outer-icon="item.appendOuterIcon"
  84. :show-size="item.showSize"
  85. variant="outlined"
  86. density="compact"
  87. v-model="item.value"
  88. :placeholder="item.placeholder || item.label"
  89. :hint="item.hint"
  90. :rules="item.rules"
  91. :label="item.label"
  92. color="primary"
  93. :persistent-hint="item.persistentHint"
  94. :loading= "item.loading"
  95. :disabled="item.disabled"
  96. :multiple="item.multiple"
  97. :success="item.success"
  98. :error="item.error"
  99. :accept="item.accept || '.xlsx, .xls, .csv, .pdf, .txt, .doc'"
  100. @change="handleChange(item)"
  101. >
  102. <template v-if="item.selfAppend" #append>
  103. <slot :name="item.selfAppend" :data="item.value"></slot>
  104. </template>
  105. </v-file-input>
  106. <template v-if="item.slotName">
  107. <slot :name="item.slotName" :item="item"></slot>
  108. </template>
  109. </div>
  110. </v-col>
  111. </template>
  112. </v-row>
  113. </div>
  114. <slot></slot>
  115. </v-form>
  116. </template>
  117. <script setup>
  118. defineOptions({ name:'components-ct-form'})
  119. import textUI from './../FormUI/TextInput'
  120. import autocompleteUI from './../FormUI/autocomplete'
  121. import comboboxUI from './../FormUI/combobox'
  122. // import comboboxZhAndEnUI from './../FormUI/comboboxZhAndEn'
  123. import radioGroupUI from './../FormUI/radioGroup'
  124. import checkboxUI from './../FormUI/checkbox'
  125. import textareaUI from './../FormUI/textArea'
  126. import cascadeUI from './../FormUI/cascade'
  127. import nestedListGroupUI from './../FormUI/nestedListGroup'
  128. import datePickerUI from './../FormUI/datePicker'
  129. import DatePicker from '@/components/DatePicker'
  130. import { ref } from 'vue'
  131. const emit = defineEmits(['change', 'inputUpdateAutocomplete'])// 定义一个或多个自定义事件
  132. const props = defineProps({items: Object})
  133. const valid = ref(false)
  134. const isValid = ref(true)
  135. const formRef = ref()
  136. const handleChange = (item) => {
  137. // console.log('handleChange', item)
  138. if (item.type === 'date' && item.value) item.option.validate = false
  139. let selectObj = {}
  140. if (item.returnSelect && item.items?.length) {
  141. selectObj = item.items.find(e => e[item.itemValue || 'value'] === item.value)
  142. }
  143. if (item?.change) item.change(item.value, item, selectObj)
  144. emit('change', false)
  145. }
  146. const validateTime = () => {
  147. isValid.value = true
  148. props.items.options.forEach((e) => {
  149. if (e.type !== 'date' || e.hide || !e.rules) return
  150. const rules = e.rules[0]
  151. const check = rules(e.value)
  152. if (typeof check === 'string') {
  153. isValid.value = false
  154. e.option.error = true
  155. e.option.errorMsg = check
  156. } else {
  157. e.option.error = false
  158. e.option.errorMsg = null
  159. }
  160. })
  161. }
  162. const validate = () => {
  163. const form = formRef.value.validate()
  164. const time = validateTime()
  165. return form && time
  166. }
  167. defineExpose({
  168. validate,
  169. formRef
  170. })
  171. </script>
  172. <style lang="scss" scoped>
  173. .position {
  174. position: relative;
  175. }
  176. .label {
  177. font-size: 14px;
  178. color: rgba(0, 0, 0, .6);
  179. }
  180. </style>