SearchBox.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <script>
  2. import { area } from '@/api/area'
  3. import { getJdjcUnit } from "@/api/index.js";
  4. import { throttle } from '@zhgkpt/utils'
  5. export default {
  6. name: "SearchBox",
  7. props: {
  8. area: {
  9. type: String,
  10. default: ""
  11. },
  12. value: {
  13. type: String,
  14. default: ''
  15. }
  16. },
  17. watch: {
  18. area: {
  19. handler(val, old) {
  20. console.log("area watch",val)
  21. if (val !== '' && val !== old) {
  22. this.changeAreaHandler(val);
  23. }
  24. },
  25. immediate: true
  26. },
  27. value: {
  28. handler(val) {
  29. this.searchValue = val
  30. },
  31. immediate: true
  32. },
  33. searchValue: {
  34. handler(val) {
  35. throttle(() => {
  36. if (val === "") {
  37. this.result = []
  38. return;
  39. }
  40. getJdjcUnit({
  41. pageNum: 1,
  42. pageSize: 10,
  43. qx: this.areaValue === "重庆市" ? "" : this.areaValue,
  44. gcjzmc: val,
  45. }).then((res) => {
  46. this.result = res.data.rows;
  47. this.total = res.data.total
  48. this.activeIndex = -1;
  49. });
  50. })()
  51. },
  52. }
  53. },
  54. data() {
  55. return {
  56. areaData: [],
  57. areaValue: '',
  58. searchValue: '',
  59. result: [],
  60. total: 0,
  61. activeIndex: -1,
  62. }
  63. },
  64. created() {
  65. area({
  66. pageNum: 1,
  67. pageSize: 100
  68. }).then(res => {
  69. this.areaData = res.data.rows
  70. })
  71. },
  72. methods: {
  73. changeAreaHandler(value) {
  74. const idx =this.areaData.findIndex(item => item.areaTitle === value)
  75. if (idx >= 0) {
  76. this.areaValue = value
  77. this.areaDetail = this.areaData[idx]
  78. this.$emit('select', this.areaDetail)
  79. this.$emit('update:area', value)
  80. }
  81. },
  82. toDetail(item) {
  83. this.$router.push(`/detail?id=${item.id}`);
  84. },
  85. toNextNode() {
  86. const temp = this.activeIndex + 1
  87. if (temp === this.result.length) {
  88. this.activeIndex = 0
  89. } else {
  90. this.activeIndex++
  91. }
  92. },
  93. toPrevNode() {
  94. const temp = this.activeIndex -1
  95. if (temp === -1) {
  96. this.activeIndex = this.result.length - 1
  97. } else {
  98. this.activeIndex--
  99. }
  100. },
  101. enterToDetail() {
  102. if (this.activeIndex < 0 || this.activeIndex >= this.result.length) return
  103. this.toDetail(this.result[this.activeIndex])
  104. }
  105. }
  106. }
  107. </script>
  108. <template >
  109. <div class="search-box">
  110. <el-select style="width: 150px;" placeholder="区域" :value="areaValue" @change="changeAreaHandler">
  111. <el-option :value="item.areaTitle" :label="item.areaTitle" v-for="(item,index) in areaData" :key="index" ></el-option>
  112. </el-select>
  113. <div style="position: relative;">
  114. <el-input @keyup.enter.native="enterToDetail()" @keyup.up.native="toPrevNode" @keyup.down.native="toNextNode" v-model="searchValue" class="search-box-input" placeholder="请输入所要搜索的建筑名称"></el-input>
  115. <div class="search-result" v-if="result.length > 0" >
  116. <div class="search-result__item" :class="{
  117. active: (index === activeIndex)
  118. }" @click="toDetail(item)" v-for="(item,index) in result" :key="index">
  119. {{ item.gcjzmc }}
  120. </div>
  121. <div class="search-result__item" v-if="total !== result.length">...</div>
  122. </div>
  123. </div>
  124. </div>
  125. </template>
  126. <style scoped lang='less'>
  127. .search-box {
  128. display: flex;
  129. gap: 2px;
  130. ::v-deep(.el-select) {
  131. width: 250px;
  132. height: 40px;
  133. .el-input__inner {
  134. border-radius: 0px;
  135. font-size: 18px;
  136. border: 0px;
  137. color: #9BC3FF;
  138. background: url('../assets/images/border.png') no-repeat;
  139. background-size: 100% 100%;
  140. background-color: transparent;
  141. }
  142. .el-input__inner::placeholder {
  143. color: #9BC3FF;
  144. }
  145. .el-input .el-select__caret {
  146. color: #9BC3FF;
  147. }
  148. }
  149. ::v-deep(.el-input.search-box-input) {
  150. .el-input__inner {
  151. border-radius: 0px;
  152. font-size: 18px;
  153. border: 1px solid #132444;
  154. color: #9BC3FF;
  155. background-color: transparent;
  156. }
  157. .el-input__inner::placeholder {
  158. color: #6C83A7;
  159. }
  160. }
  161. .search-result {
  162. background-size: 100% 100%;
  163. background-color: transparent;
  164. display: flex;
  165. flex-direction: column;
  166. color: #9BC3FF;
  167. background-color: #132444aa;
  168. .search-result__item {
  169. padding: 8px;
  170. font-size: 18px;
  171. text-overflow: ellipsis;
  172. white-space: nowrap;
  173. &:hover,&.active {
  174. background-color: rgba(0, 213, 255, 0.3);
  175. cursor: pointer;
  176. color: #fff;
  177. }
  178. }
  179. }
  180. ::v-deep(.el-button) {
  181. border: none;
  182. width: 120px;
  183. height: 40px;
  184. color: #9BC3FF;
  185. }
  186. }
  187. </style>