c-search.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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. </el-col>
  53. <el-col :span="24" class="slot"><slot name="isslot"></slot></el-col>
  54. </el-row>
  55. </div>
  56. </template>
  57. <script lang="ts" setup>
  58. import { ref, toRefs } from 'vue';
  59. import type { Ref } from 'vue';
  60. import { useRoute } from 'vue-router';
  61. const route = useRoute();
  62. import _ from 'lodash';
  63. interface fieldsItem {
  64. model: string;
  65. type: string;
  66. // readonly: string;
  67. options: object;
  68. custom: string;
  69. // required: string;
  70. // limit: number | undefined;
  71. isSearch: boolean;
  72. }
  73. const props = defineProps({
  74. is_title: { type: Boolean, default: true },
  75. is_search: { type: Boolean, default: false },
  76. is_back: { type: Boolean, default: false },
  77. fields: { type: Array<fieldsItem> },
  78. title: { type: String },
  79. tip: { type: String },
  80. remark: { type: String }
  81. });
  82. const { is_title } = toRefs(props);
  83. const { is_search } = toRefs(props);
  84. const { is_back } = toRefs(props);
  85. const { fields } = toRefs(props);
  86. const { title } = toRefs(props);
  87. const { tip } = toRefs(props);
  88. const { remark } = toRefs(props);
  89. let form: Ref<{}> = ref({});
  90. const emit = defineEmits(['search', 'toReset', 'toBack', 'dataChange']);
  91. const toSubmit = () => {
  92. const obj = _.pickBy(form.value);
  93. emit('search', { ...obj });
  94. };
  95. // 重置
  96. const toReset = () => {
  97. form.value = {};
  98. emit('search', form.value);
  99. };
  100. // 文字描述
  101. const getField = (item: any, data: any) => {
  102. let res = _.get(data, item, null);
  103. if (item === 'type') res = res === null ? `text` : res;
  104. if (item === 'place') res = res === null ? `请输入${data.label}` : res;
  105. if (item === 'required') res = res === null ? false : res;
  106. if (item === `error`) res = res === null ? `${data.label}错误` : res;
  107. return res;
  108. };
  109. // 获取输入值
  110. const dataChange = (model: string) => {
  111. const value = form.value[model];
  112. emit('dataChange', { model, value });
  113. };
  114. // 返回
  115. const toBack = () => {
  116. emit('toBack');
  117. };
  118. </script>
  119. <style lang="scss" scoped>
  120. .title {
  121. margin: 0 0 5px 0;
  122. .title_1 {
  123. margin: 0 0 5px 0;
  124. span:first-child {
  125. font-size: 20px;
  126. font-weight: 700;
  127. margin-right: 10px;
  128. }
  129. span:last-child {
  130. font-size: 14px;
  131. color: #979797;
  132. }
  133. }
  134. .title_2 {
  135. span {
  136. color: #8baae7;
  137. font-size: 14px;
  138. margin-top: 10px;
  139. }
  140. }
  141. }
  142. .search {
  143. margin: 0 0 10px 0;
  144. .form {
  145. display: flex;
  146. flex-direction: row;
  147. flex-wrap: wrap;
  148. .form_1 {
  149. padding: 0 0 0 10px;
  150. .el-form-item {
  151. float: left;
  152. width: 100%;
  153. margin: 0 0 10px 0;
  154. }
  155. .el-select {
  156. width: 100%;
  157. }
  158. }
  159. }
  160. .btn {
  161. text-align: right;
  162. }
  163. }
  164. .back {
  165. text-align: left;
  166. margin: 0 0 10px 0;
  167. }
  168. </style>