custom-search-bar.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <template>
  2. <div id="custom-search-bar">
  3. <el-form ref="formRef" :model="form" :label-width="labelWidth" class="form" @submit.prevent :inline="true">
  4. <el-form-item v-for="item in fields" :key="`form-field-${item.model}`" :label="getField('label', item)" :prop="item.model" :required="item.required">
  5. <template v-if="item.custom">
  6. <slot :name="item.model" v-bind="{ item }"></slot>
  7. </template>
  8. <template v-else>
  9. <template v-if="item.type === 'numbers'">
  10. <el-input-number v-model="form[item.model]" :placeholder="getField('placeholder', item)" @change="dataChange(item.model)" style="width: 100%" />
  11. </template>
  12. <template v-else-if="item.type === 'radio'">
  13. <el-radio-group v-model="form[item.model]" :type="item.type" v-bind="item.options" @change="dataChange(item.model)">
  14. <slot :name="item.model" v-bind="{ item }"></slot>
  15. </el-radio-group>
  16. </template>
  17. <template v-else-if="item.type === 'checkbox'">
  18. <el-checkbox-group v-model="form[item.model]" :type="item.type" v-bind="item.options">
  19. <slot :name="item.model" v-bind="{ item }"></slot>
  20. </el-checkbox-group>
  21. </template>
  22. <template v-else-if="item.type === 'select'">
  23. <el-select
  24. clearable
  25. filterable
  26. allow-create
  27. default-first-option
  28. v-model="form[item.model]"
  29. :type="item.type"
  30. :placeholder="getField('selectplaceholder', item)"
  31. v-bind="item.options"
  32. @change="dataChange(item.model)"
  33. style="width: 100%; min-width: 200px"
  34. >
  35. <slot :name="item.model" v-bind="{ item }"></slot>
  36. </el-select>
  37. </template>
  38. <template v-else-if="item.type === 'selectMany'">
  39. <el-select
  40. filterable
  41. clearable
  42. multiple
  43. collapse-tags
  44. v-model="form[item.model]"
  45. :type="item.type"
  46. :placeholder="getField('selectplaceholder', item)"
  47. v-bind="item.options"
  48. @change="dataChange(item.model)"
  49. style="width: 100%; min-width: 200px"
  50. >
  51. <slot :name="item.model" v-bind="{ item }"></slot>
  52. </el-select>
  53. </template>
  54. <template v-else-if="item.type === `year` || item.type == 'month' || item.type == 'date' || item.type == 'daterange' || item.type == 'datetime' || item.type == 'datetimerange'">
  55. <el-date-picker
  56. v-model="form[item.model]"
  57. :type="item.type"
  58. :placeholder="getField('selectplaceholder', item)"
  59. :format="getDateFormat(item.type)"
  60. :value-format="getDateFormat(item.type)"
  61. v-bind="item.options"
  62. @change="dataChange(item.model)"
  63. range-separator="至"
  64. style="width: 100%"
  65. >
  66. </el-date-picker>
  67. </template>
  68. <template v-else-if="item.type === `time`">
  69. <el-time-picker
  70. v-model="form[item.model]"
  71. :placeholder="getField('selectplaceholder', item)"
  72. :format="getDateFormat(item.type)"
  73. :value-format="getDateFormat(item.type)"
  74. v-bind="item.options"
  75. @change="dataChange(item.model)"
  76. style="width: 100%"
  77. >
  78. </el-time-picker>
  79. </template>
  80. <template v-else-if="item.type === `inputnumber`">
  81. <el-input-number v-model="form[item.model]" :placeholder="getField('placeholder', item)" v-bind="item.options" @change="dataChange(item.model)" style="width: 100%"></el-input-number>
  82. </template>
  83. <template v-else>
  84. <el-input
  85. clearable
  86. v-model="form[item.model]"
  87. :type="getField('type', item)"
  88. :placeholder="getField('placeholder', item)"
  89. :show-password="getField('type', item) === 'password'"
  90. v-bind="item.options"
  91. @change="dataChange(item.model)"
  92. ></el-input>
  93. </template>
  94. </template>
  95. </el-form-item>
  96. <el-form-item v-if="fields.length > 0">
  97. <el-button type="primary" @click="toClick">{{ $t('common.search') }}</el-button>
  98. <el-button type="default" @click="toReset">{{ $t('common.reset') }}</el-button>
  99. </el-form-item>
  100. </el-form>
  101. </div>
  102. </template>
  103. <script setup>
  104. import { get } from 'lodash-es'
  105. const props = defineProps({
  106. modelValue: { type: Object },
  107. fields: { type: Array, default: () => [] }
  108. })
  109. const emits = defineEmits(['update:modelValue', 'dataChange', 'search'])
  110. const formRef = ref()
  111. const form = computed({
  112. get() {
  113. return props.modelValue
  114. },
  115. set(value) {
  116. console.log(value)
  117. emits('update:modelValue', value)
  118. }
  119. })
  120. const toClick = () => {
  121. emits('search')
  122. }
  123. const toReset = () => {
  124. emits('reset')
  125. }
  126. const getField = (item, data) => {
  127. let res = get(data, item, null)
  128. if (item === 'type') res = res === null ? `text` : res
  129. if (item === 'placeholder') res = res === null ? `请输入${data.label}` : res
  130. if (item === `selectplaceholder`) res = res === null ? `请选择${data.label}` : res
  131. if (item === 'required') res = res === null ? false : res
  132. if (item === `error`) res = res === null ? `${data.label}错误` : res
  133. return res
  134. }
  135. const dataChange = (model) => {
  136. const value = form.value[model]
  137. emits('dataChange', { model, value })
  138. }
  139. const getDateFormat = (e) => {
  140. if (e === 'year') return 'YYYY'
  141. if (e === 'month') return 'MM'
  142. if (e === 'date') return 'YYYY-MM-DD'
  143. if (e === 'daterange') return 'YYYY-MM-DD'
  144. if (e === 'datetime') return 'YYYY-MM-DD HH:mm:ss'
  145. if (e === 'datetimerange') return 'YYYY-MM-DD HH:mm:ss'
  146. if (e === 'time') return 'HH:mm:ss'
  147. }
  148. </script>
  149. <style scoped></style>