c-search.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <template>
  2. <div id="c-search">
  3. <el-row>
  4. <el-col :span="24" class="title" v-if="is_title">
  5. <el-col :span="24" class="title_1">
  6. <span>{{ title || $route.meta.title }}</span>
  7. <span>{{ tip }}</span>
  8. </el-col>
  9. <el-col :span="24" class="title_2">
  10. <span>{{ remark }}</span>
  11. </el-col>
  12. </el-col>
  13. <el-col :span="24" class="search" v-if="is_search">
  14. <el-form ref="formRef" :model="form" label-width="auto">
  15. <el-col :span="24" class="form">
  16. <template v-for="(item, index) in fields">
  17. <el-col :span="8" class="form_1" :key="'form-field-' + index" v-if="item.isSearch == true">
  18. <el-form-item :label="getField('label', item)" :prop="item.model">
  19. <template v-if="!item.custom">
  20. <template v-if="item.type === 'select'">
  21. <el-select v-model="form[item.model]" v-bind="item.options" filterable clearable @change="dataChange(item.model)">
  22. <slot :name="item.model" v-bind="{ item }"></slot>
  23. </el-select>
  24. </template>
  25. <template v-else>
  26. <el-input
  27. v-model="form[item.model]"
  28. :type="getField('type', item)"
  29. :placeholder="getField('place', item)"
  30. clearable
  31. v-bind="item.options"
  32. @change="dataChange(item.model)"
  33. ></el-input>
  34. </template>
  35. </template>
  36. <template v-else>
  37. <slot :name="item.model" v-bind="{ item }"></slot>
  38. <!-- <el-input v-model="form[item.model]" clearable :placeholder="`输入${item.label}`"></el-input> -->
  39. </template>
  40. </el-form-item>
  41. </el-col>
  42. </template>
  43. </el-col>
  44. <el-col :span="24" class="btn">
  45. <el-button type="primary" @click="toSubmit()">查询</el-button>
  46. <el-button type="danger" @click="toReset()">重置</el-button>
  47. </el-col>
  48. </el-form>
  49. </el-col>
  50. <el-col :span="24" class="back" v-if="is_back">
  51. <el-button type="primary" @click="toBack()">返回</el-button>
  52. <slot name="custombtn"></slot>
  53. </el-col>
  54. <el-col :span="24" class="slot">
  55. <slot name="isslot"></slot>
  56. </el-col>
  57. </el-row>
  58. </div>
  59. </template>
  60. <script lang="ts" setup>
  61. import { ref, toRefs } from 'vue';
  62. import type { Ref } from 'vue';
  63. import _ from 'lodash';
  64. interface fieldsItem {
  65. model: string;
  66. type: string;
  67. // readonly: string;
  68. options: object;
  69. custom: string;
  70. // required: string;
  71. // limit: number | undefined;
  72. isSearch: boolean;
  73. }
  74. const props = defineProps({
  75. is_title: { type: Boolean, default: true },
  76. is_search: { type: Boolean, default: false },
  77. is_back: { type: Boolean, default: false },
  78. fields: { type: Array<fieldsItem> },
  79. title: { type: String },
  80. tip: { type: String },
  81. remark: { type: String },
  82. });
  83. const { is_title } = toRefs(props);
  84. const { is_search } = toRefs(props);
  85. const { is_back } = toRefs(props);
  86. const { fields } = toRefs(props);
  87. const { title } = toRefs(props);
  88. const { tip } = toRefs(props);
  89. const { remark } = toRefs(props);
  90. let form: Ref<{}> = ref({});
  91. const emit = defineEmits(['search', 'toReset', 'toBack', 'dataChange']);
  92. const toSubmit = () => {
  93. const obj = _.pickBy(form.value);
  94. emit('search', { ...obj });
  95. };
  96. // 重置
  97. const toReset = () => {
  98. form.value = {};
  99. emit('search', form.value);
  100. };
  101. // 文字描述
  102. const getField = (item: any, data: any) => {
  103. let res = _.get(data, item, null);
  104. if (item === 'type') res = res === null ? `text` : res;
  105. if (item === 'place') res = res === null ? `请输入${data.label}` : res;
  106. if (item === 'required') res = res === null ? false : res;
  107. if (item === `error`) res = res === null ? `${data.label}错误` : res;
  108. return res;
  109. };
  110. // 获取输入值
  111. const dataChange = (model: string) => {
  112. const value = form.value[model];
  113. emit('dataChange', { model, value });
  114. };
  115. // 返回
  116. const toBack = () => {
  117. emit('toBack');
  118. };
  119. </script>
  120. <style lang="scss" scoped>
  121. .title {
  122. margin: 0 0 5px 0;
  123. .title_1 {
  124. margin: 0 0 5px 0;
  125. span:first-child {
  126. font-size: 20px;
  127. font-weight: 700;
  128. margin-right: 10px;
  129. }
  130. span:last-child {
  131. font-size: 14px;
  132. color: #979797;
  133. }
  134. }
  135. .title_2 {
  136. span {
  137. color: #8baae7;
  138. font-size: 14px;
  139. margin-top: 10px;
  140. }
  141. }
  142. }
  143. .search {
  144. margin: 0 0 10px 0;
  145. .form {
  146. display: flex;
  147. flex-direction: row;
  148. flex-wrap: wrap;
  149. .form_1 {
  150. padding: 0 0 0 10px;
  151. .el-form-item {
  152. float: left;
  153. width: 100%;
  154. margin: 0 0 10px 0;
  155. }
  156. .el-select {
  157. width: 100%;
  158. }
  159. }
  160. }
  161. .btn {
  162. text-align: right;
  163. }
  164. }
  165. .back {
  166. text-align: left;
  167. margin: 0 0 10px 0;
  168. }
  169. </style>