newsearch.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <!--
  2. * @Author: zZ(zzy6937@qq.com)
  3. * @Date: 2019-11-01 11:11:28
  4. * @LastEditors: zwy
  5. * @LastEditTime: 2021-02-02 18:22:13
  6. * @Description: 通用搜索
  7. -->
  8. <template>
  9. <form class="zz-search" ref="searchForm" @submit.prevent="search" action="">
  10. <div class="search-normal">
  11. <div class="col" v-for='(item, index) in normal' :key='index'>
  12. <span class="search-box">
  13. <span v-if="item.label" class='search-label'>{{item.label}}</span>
  14. <span class="search-content">
  15. <el-select v-if='item.options' :class="item.class" v-model="query[item.prop]" :placeholder="item.placeholder" clearable>
  16. <el-option v-for='(o, ot) in item.options' :key='ot' :label="o.label" :value="o.value || o.id"></el-option>
  17. </el-select>
  18. <slot v-else-if='item.slot' :name="item.slot"></slot>
  19. <el-input v-else :type="item.type" @input="(val)=> inputChange(val, item)" :class="item.class" :placeholder="item.placeholder" v-model.trim="query[item.prop]" clearable></el-input>
  20. </span>
  21. </span>
  22. </div>
  23. <el-button plain v-if='more.length' @click="showMore = !showMore" class="more-search el-mgRight-md">
  24. 高级搜索<i :class="showMore ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" class="el-icon--right"></i></el-button>
  25. <el-button v-if="normal.length && !showMore" native-type="submit" :disabled="btnDisabled" type='primary' class='search-btn' icon="el-icon-search">搜索</el-button>
  26. <!-- <el-button class="button-has-icon" v-if='more.length' @click="showMore = !showMore">
  27. 高级搜索<i class="el-icon-caret-bottom el-icon--right" :class="{'top': showMore}"></i></el-button>
  28. <el-button type="primary" native-type="submit" v-if='normal.length && !showMore'>搜索</el-button> -->
  29. </div>
  30. <el-collapse-transition>
  31. <div class='search-more' v-show="showMore">
  32. <div v-for="(item, index) in more" :key='index' class="col" :class="{'margin0': (index+1) % 6 === 0}">
  33. <span class="search-box">
  34. <span v-if="item.label" class='search-label'>{{item.label}}</span>
  35. <span class="search-content">
  36. <el-select v-if='item.options' :class="item.class" v-model="query[item.prop]" :placeholder="item.placeholder" clearable>
  37. <el-option v-for='(o, ot) in item.options' :key='ot' :label="o.label" :value="o.value || o.id"></el-option>
  38. </el-select>
  39. <slot v-else-if='item.slot' :name="item.slot"></slot>
  40. <el-input v-else :type="item.type" @input="(val)=> inputChange(val, item)" :class="item.class" :placeholder="item.placeholder" v-model.trim="query[item.prop]" clearable></el-input>
  41. </span>
  42. </span>
  43. </div>
  44. <div class="col">
  45. <el-button type="primary" native-type="submit" icon="el-icon-search">搜索</el-button>
  46. <el-button class="reset_button" @click="reset">重置</el-button>
  47. </div>
  48. </div>
  49. </el-collapse-transition>
  50. <slot name='right-opt'></slot>
  51. </form>
  52. </template>
  53. <script>
  54. /**
  55. * @description: 搜索控件
  56. * @param {Object} normal: 基本搜索条件
  57. * @param {Object} more: 更多搜索条件
  58. * @param {Object} query: 绑定的数据对象
  59. * @return {type}: null
  60. * @author: zZ(zzy6937@qq.com)
  61. */
  62. export default {
  63. name: 'dmp-newsearch',
  64. props: {
  65. normal: {
  66. type: Array,
  67. default() {
  68. return []
  69. }
  70. },
  71. more: {
  72. type: Array,
  73. default() {
  74. return []
  75. }
  76. },
  77. query: {
  78. type: Object,
  79. default() {
  80. return {}
  81. }
  82. },
  83. resetQuery: {
  84. type: Object,
  85. default() {
  86. return {}
  87. }
  88. },
  89. // 不重置的字段集合
  90. noSetKeys: {
  91. type: Array,
  92. default() {
  93. return []
  94. }
  95. },
  96. btnDisabled: {
  97. type: Boolean,
  98. default() {
  99. return false
  100. }
  101. }
  102. },
  103. data() {
  104. return {
  105. showMore: false
  106. }
  107. },
  108. methods: {
  109. search() {
  110. //this.showMore = false;
  111. this.$emit('search');
  112. },
  113. reset() {
  114. const set = new Set(this.noSetKeys)
  115. if (_.isEmpty(this.resetQuery)) {
  116. Object.keys(this.query).forEach((item) => {
  117. if (!set.has(item)) {
  118. this.query[item] = ''
  119. }
  120. })
  121. } else {
  122. const obj = {}
  123. Object.keys(this.resetQuery).forEach((item) => {
  124. if (!set.has(item)) {
  125. obj[item] = ''
  126. }
  127. })
  128. Object.assign(this.query, obj);
  129. }
  130. this.$emit("reset");
  131. },
  132. inputChange(val, item) {
  133. const {type, maxlength} = item;
  134. if(type == 'number' && maxlength) {
  135. if(val.toString().length > maxlength) {
  136. this.query[item.prop] = Number(val.toString().slice(0, maxlength));
  137. }
  138. }
  139. }
  140. },
  141. /* mounted() {
  142. this.$refs.searchForm.onkeydown = (event) => {
  143. const e = event || window.event;
  144. if (e && e.keyCode == 13) {
  145. this.search();
  146. }
  147. };
  148. }, */
  149. created() {
  150. const data = {}
  151. this.more.forEach((item) => {
  152. data[item.prop] = ''
  153. })
  154. this.normal.forEach((item) => {
  155. data[item.prop] = ''
  156. })
  157. this.data = data;
  158. }
  159. /* beforeDestroy() {
  160. this.$refs.searchForm.onkeydown = undefined;
  161. } */
  162. }
  163. </script>
  164. <style lang="scss">
  165. .zz-search {
  166. position:relative;
  167. .col {
  168. display:inline-block;
  169. vertical-align:middle;
  170. .el-input,.el-select,.el-calendar,.el-cascader {
  171. width: 180px;
  172. input::-webkit-outer-spin-button,input::-webkit-inner-spin-button {
  173. -webkit-appearance: none;
  174. margin: 0;
  175. }
  176. input[type="number"] {
  177. -moz-appearance: textfield;
  178. }
  179. }
  180. .inherit-css {
  181. width: 140px !important;
  182. .el-input {
  183. width: 100% !important;
  184. }
  185. }
  186. .min-css{
  187. width: 110px !important;
  188. .el-input {
  189. width: 100% !important;
  190. }
  191. }
  192. }
  193. .search-box {
  194. display: flex;
  195. align-items:center;
  196. .search-label {
  197. margin-right: 0.520833333333333vw;
  198. color: #3b4045;
  199. font-size: 0.729166666666667vw;
  200. vertical-align: middle;
  201. display: inline-block;
  202. //min-width vw(60)
  203. text-align: justify;
  204. text-align-last: justify;
  205. }
  206. }
  207. .search-normal {
  208. // margin: 20px 0;
  209. .col, .el-button {
  210. margin-right: 20px;
  211. }
  212. .el-button {
  213. vertical-align: middle;
  214. margin-right: 15px;
  215. }
  216. .el-button +.el-button {
  217. margin-left: 0;
  218. }
  219. &:before {
  220. content:' ';
  221. width: 0;
  222. height: 100%;
  223. display: inline-block;
  224. vertical-align: middle;
  225. }
  226. .button-has-icon {
  227. padding-right: 5px;
  228. .el-icon-caret-bottom {
  229. transition: all .3s;
  230. &.top {
  231. transform: scale(0.8) rotate(180deg);
  232. }
  233. }
  234. }
  235. }
  236. .search-more {
  237. padding: 0 15px;
  238. font-size: 0;
  239. width: 100%;
  240. .el-input, .el-select {
  241. width: 100%;
  242. }
  243. .col {
  244. margin-right: 20px;
  245. margin-bottom: 20px;
  246. .el-input,.el-select,.el-calendar,.el-cascader {
  247. width: 180px;
  248. }
  249. }
  250. .el-button {
  251. min-width: 68px;
  252. }
  253. .reset_button{
  254. border: 1px solid #0D87F9;
  255. opacity: 1;
  256. border-radius: 4px;
  257. }
  258. .el-button--default {
  259. margin-left: 20px;
  260. }
  261. .dmp-date-picker .el-input__inner {
  262. border: none;
  263. padding: 0 15px;
  264. }
  265. }
  266. .opt {
  267. position: absolute;
  268. top: 0;
  269. right: 0;
  270. img{
  271. width:30px;
  272. height:30px;
  273. margin-right: 10px;
  274. }
  275. &>.dmp-icon-big, &>.dmp-icon-big .dmp-icon-big{
  276. width: 32px;
  277. height: 32px;
  278. margin-left: 20px;
  279. font-size: 14px !important;
  280. justify-content: center;
  281. display: flex;
  282. align-items: center;
  283. padding: 0;
  284. }
  285. &>.dmp-icon-big .dmp-icon-big {
  286. margin: 0;
  287. }
  288. }
  289. }
  290. @media screen and (min-width: 1600px) {
  291. .zz-search {
  292. .search-normal .col {
  293. .el-input,.el-select,.el-calendar,.el-cascader {
  294. width: 180px;
  295. }
  296. }
  297. }
  298. }
  299. @media screen and (max-width: 1599px) {
  300. .zz-search {
  301. .search-normal .col {
  302. .el-input,.el-select,.el-calendar,.el-cascader {
  303. width: 125px !important
  304. }
  305. }
  306. }
  307. }
  308. </style>