FormComp.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <!-- eslint-disable vue/no-mutating-props -->
  2. <script setup lang="ts">
  3. import type { BasicFormItem } from '@/types/form'
  4. import type { UploadProps } from 'element-plus'
  5. import { useUserStore } from '@/stores/user'
  6. import { ACCESS_TOKEN } from '@/utils/constants'
  7. interface Props {
  8. modelValue: any
  9. item: BasicFormItem
  10. }
  11. const props = defineProps<Props>()
  12. const emits = defineEmits(['update:modelValue'])
  13. const baseApi = import.meta.env.VITE_BASE_API
  14. const modelValue = computed({
  15. get: () => props.modelValue,
  16. set: value => emits('update:modelValue', value)
  17. })
  18. const placeholder = (item: BasicFormItem) => {
  19. if (['select', 'cascader', 'date-picker', 'time-picker', 'time-select', 'dict'].includes(item.type)) {
  20. return '请选择' + item.label
  21. } else {
  22. return '请输入' + item.label
  23. }
  24. }
  25. if (props.item.request) {
  26. props.item.request(props.item).then((res: any) => {
  27. props.item.options = res
  28. })
  29. }
  30. const user = useUserStore()
  31. const headers = reactive({
  32. [ACCESS_TOKEN]: user.token
  33. })
  34. // 图片上传
  35. // const handleUploadSuccess: UploadProps['onSuccess'] = response => {
  36. // modelValue.value = import.meta.env.VITE_BASE_PATH + response.data
  37. // }
  38. </script>
  39. <template>
  40. <el-cascader
  41. v-if="item.type === 'cascader'"
  42. style="width: 100%"
  43. v-model="modelValue"
  44. v-bind="item.props"
  45. v-on="item.events || {}"
  46. :placeholder="item.placeholder || placeholder(item)"
  47. >
  48. <template #[slot.name]="{ node, data }" v-for="slot in item.slots" :key="slot.alias">
  49. <slot :name="slot.alias" :node="node" :data="data"></slot>
  50. </template>
  51. </el-cascader>
  52. <el-date-picker
  53. v-else-if="item.type === 'date-picker'"
  54. style="width: 100%"
  55. v-model="modelValue"
  56. v-bind="item.props"
  57. v-on="item.events || {}"
  58. :placeholder="item.placeholder || placeholder(item)"
  59. >
  60. <template #[slot.name]="slotProps" v-for="slot in item.slots" :key="slot.alias">
  61. <slot :name="slot.alias" v-bind="slotProps"></slot>
  62. </template>
  63. </el-date-picker>
  64. <el-upload
  65. v-else-if="item.type === 'upload'"
  66. v-model:file-list="modelValue"
  67. :action="baseApi + '/file/upload'"
  68. :headers="headers"
  69. v-bind="item.props"
  70. v-on="item.events || {}"
  71. >
  72. <template #[slot.name]="slotProps" v-for="slot in item.slots" :key="slot.alias">
  73. <slot :name="slot.alias" v-bind="slotProps"></slot>
  74. </template>
  75. </el-upload>
  76. <el-select
  77. v-else-if="item.type === 'select'"
  78. v-model="modelValue"
  79. v-bind="item.props"
  80. :placeholder="item.placeholder || placeholder(item)"
  81. v-on="item.events || {}"
  82. >
  83. <el-option
  84. v-for="(option, index) in item.options"
  85. :label="option.label"
  86. :value="option.value"
  87. :key="index"
  88. v-bind="option.props"
  89. >
  90. </el-option>
  91. <template #[slot.name]="slotProps" v-for="slot in item.slots" :key="slot.alias">
  92. <slot :name="slot.alias" v-bind="slotProps"></slot>
  93. </template>
  94. </el-select>
  95. <component
  96. v-else
  97. :is="'el-' + item.type"
  98. v-model="modelValue"
  99. v-bind="item.props"
  100. :placeholder="item.placeholder || placeholder(item)"
  101. v-on="item.events || {}"
  102. >
  103. <template v-if="item.type === 'radio-group'">
  104. <el-radio v-for="(option, index) in item.options" :label="option.label" :key="index" v-bind="option.props">
  105. {{ option.value }}
  106. </el-radio>
  107. </template>
  108. <template v-if="item.type === 'checkbox-group'">
  109. <el-checkbox v-for="(option, index) in item.options" :label="option.label" :key="index" v-bind="option.props">
  110. {{ option.value }}
  111. </el-checkbox>
  112. </template>
  113. <template #[slot.name]="slotProps" v-for="slot in item.slots" :key="slot.alias">
  114. <slot :name="slot.alias" v-bind="slotProps"></slot>
  115. </template>
  116. </component>
  117. </template>
  118. <style lang="scss" scoped></style>