index.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. <template>
  2. <div class="SearchWrapper" v-if="!isEmpty(props?.fields)">
  3. <a-card>
  4. <a-form ref="formRef">
  5. <a-row :gutter="[10, 10]">
  6. <a-col :span="fieldSpan || 3" v-for="(item, index) in props.fields" :key="index" v-show="item.visible">
  7. <a-form-item :label="item.label" :name="item.field">
  8. <component
  9. :is="item?.component"
  10. v-model:value="props.data[item?.field]"
  11. v-model:checked="props.data[item?.field]"
  12. :placeholder="item.placeholder"
  13. v-bind="item?.componentProps"
  14. />
  15. </a-form-item>
  16. </a-col>
  17. <a-col :span="btnSpan">
  18. <div class="search-btn">
  19. <a-space>
  20. <a-button type="primary" :icon="h(SearchOutlined)" @click="searchHandler">查询</a-button>
  21. <a-button :icon="h(ClearOutlined)" @click="resetHandler">重置</a-button>
  22. <a-space v-if="props.fields.length > 1">
  23. <a-button type="dashed" :icon="h(UpOutlined)" @click="toggleHandler" v-if="isZheDie">收起</a-button>
  24. <a-button type="dashed" :icon="h(DownOutlined)" @click="toggleHandler" v-if="!isZheDie">展开</a-button>
  25. </a-space>
  26. </a-space>
  27. <div class="search-right">
  28. <slot name="searchRight"></slot>
  29. </div>
  30. </div>
  31. </a-col>
  32. </a-row>
  33. </a-form>
  34. </a-card>
  35. </div>
  36. </template>
  37. <script setup>
  38. import { ref, h, computed } from 'vue';
  39. import { ClearOutlined, SearchOutlined, UpOutlined, DownOutlined } from '@ant-design/icons-vue';
  40. import { isEmpty } from 'lodash';
  41. const props = defineProps(['fields', 'data', 'onSearch', 'onReset', 'onToggle', 'fieldSpan']);
  42. const emits = defineEmits(['search', 'reset']);
  43. const formRef = ref(null);
  44. const isZheDie = ref(false);
  45. const searchHandler = () => {
  46. emits('search');
  47. };
  48. const resetHandler = () => {
  49. emits('reset');
  50. };
  51. const toggleHandler = () => {
  52. isZheDie.value = !isZheDie.value;
  53. props?.onToggle();
  54. };
  55. const btnSpan = computed(() => {
  56. const num = props.fields.filter((item) => item.visible).length;
  57. const fieldSpanNum = Number(props.fieldSpan || 3);
  58. const totalFieldSpanNum = num * fieldSpanNum;
  59. return 24 - totalFieldSpanNum % 24;
  60. });
  61. </script>
  62. <style lang="scss" scoped>
  63. .SearchWrapper {
  64. width: 100%;
  65. padding-bottom: 10px;
  66. :deep(.ant-card-body) {
  67. padding: 20px;
  68. }
  69. :deep(.ant-form-item) {
  70. margin-bottom: 0;
  71. }
  72. .search-btn {
  73. display: flex;
  74. justify-content: space-between;
  75. align-items: center;
  76. .search-right {
  77. flex: 1;
  78. display: flex;
  79. align-items: center;
  80. justify-content: flex-end;
  81. }
  82. }
  83. .field-items {
  84. display: flex;
  85. flex-wrap: wrap;
  86. gap: 10px;
  87. width: 100%;
  88. .field-item {
  89. width: 200px;
  90. }
  91. .btn-list {
  92. display: flex;
  93. flex: 1;
  94. justify-content: space-between;
  95. }
  96. }
  97. }
  98. </style>