SearchHeader.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <template>
  2. <div class="search-content com-mobile-header mobile-search-header" :class="expandClass">
  3. <a @click="goLastPage"><i class="iconfont icon-fanhui"></i></a>
  4. <input type="text" v-model="keyword" @input="onKeywordInput()" :placeholder="placeholder" @keyup.13="onSearch()">
  5. <span @click="onSearch()"><i class="iconfont icon-sousuo"></i></span>
  6. <ul v-if="emptyStatus && keyword && keyword !== '' && showSimilarWord">
  7. <template v-if="similarList.store && similarList.store.length && (similarType == 'all' || similarType == 'store')">
  8. <template v-if="type === 'supplier' || type === 'default'">
  9. <li class="title text-ellipse" v-if="similarType == 'all'" v-text="type === 'supplier' ? '公司名' : type === 'default' ? '店铺名' : ''">公司名</li>
  10. <li class="text-ellipse" v-for="store in similarList.store.slice(0, 8)" @click="onSearch(store.name, 'store', $event)">{{store.name}}</li>
  11. </template>
  12. <template v-if="type=== 'purchase' && user.logged">
  13. <li class="title text-ellipse" v-if="similarType == 'all'">公司</li>
  14. <li class="text-ellipse" v-for="store in similarList.store.slice(0, 8)" @click="onSearch(store.name, 'store', $event)">{{store.name}}</li>
  15. </template>
  16. </template>
  17. <template v-if="similarList.brand && similarList.brand.length && (similarType == 'all' || similarType == 'brand')">
  18. <li class="title text-ellipse" v-if="similarType == 'all'">品牌</li>
  19. <li class="text-ellipse" v-for="brand in similarList.brand.slice(0, 8)" @click="onSearch(brand.nameEn, 'brand', $event)">{{brand.nameEn}}</li>
  20. </template>
  21. <template v-if="similarList.kind && similarList.kind.length && (similarType == 'all' || similarType == 'kind')">
  22. <li class="title text-ellipse" v-if="similarType == 'all'">物料名称</li>
  23. <li class="text-ellipse" v-for="kind in similarList.kind.slice(0, 8)" @click="onSearch(kind.nameCn, 'kind', $event)">{{kind.nameCn}}</li>
  24. </template>
  25. <template v-if="similarList.component && similarList.component.length && (similarType == 'all' || similarType == 'code')">
  26. <li class="title text-ellipse" v-if="similarType == 'all'">型号</li>
  27. <li class="text-ellipse" v-for="code in similarList.component.slice(0, 8)" @click="onSearch(code.code, 'code', $event)">{{code.code}}</li>
  28. </template>
  29. </ul>
  30. </div>
  31. </template>
  32. <script>
  33. import {scrollTo} from '~utils/scroll'
  34. export default {
  35. props: {
  36. placeholder: {
  37. type: String,
  38. default: '请输入要查找的内容'
  39. },
  40. similarUrl: { // 联想词url
  41. type: String,
  42. default: '/search/similarKeywords'
  43. },
  44. type: { // 搜索类型
  45. type: String,
  46. default: 'default'
  47. },
  48. showSimilar: { // 是否显示联想词
  49. type: Boolean,
  50. default: true
  51. },
  52. outerKeyword: { // 提示keyword
  53. type: String,
  54. default: ''
  55. },
  56. similarType: { // 选择出现的联想词类型
  57. type: String,
  58. default: 'all'
  59. },
  60. useMatchRule: { // 使用既定的匹配规则
  61. type: Boolean,
  62. default: true
  63. },
  64. expandClass: {
  65. type: String,
  66. default: ''
  67. }
  68. },
  69. data () {
  70. return {
  71. keyword: '',
  72. similarList: {},
  73. showSimilarWord: false,
  74. searchKeyword: '',
  75. clickCount: 0
  76. }
  77. },
  78. watch: {
  79. outerKeyword: {
  80. handler: function (val) {
  81. this.keyword = val
  82. },
  83. immediate: true
  84. }
  85. },
  86. mounted () {
  87. this.$nextTick(() => {
  88. document.onclick = () => {
  89. this.showSimilarWord = false
  90. }
  91. })
  92. },
  93. computed: {
  94. emptyStatus () {
  95. let similarList = this.similarList
  96. return (similarList.store && similarList.store.length) ||
  97. (similarList.component && similarList.component.length) ||
  98. (similarList.brand && similarList.brand.length) ||
  99. (similarList.kind && similarList.kind.length)
  100. }
  101. },
  102. methods: {
  103. onSearch: function (key, type, e) {
  104. if (e) {
  105. e.stopPropagation()
  106. }
  107. // if (key === this.searchKeyword || this.keyword === this.searchKeyword) {
  108. // return
  109. // }
  110. if (key || !this.useMatchRule) {
  111. this.keyword = key || this.keyword
  112. this.$emit('searchAction', {
  113. keyword: this.keyword,
  114. type: type
  115. })
  116. } else {
  117. let sType = null
  118. if (this.keyword && this.keyword !== '' && this.similarList.brand) { // 防止接口报错无法搜索
  119. if (this.similarList.store[0] && this.keyword === this.similarList.store[0].name) {
  120. sType = 'store'
  121. } else if (this.similarList.brand[0] && this.keyword === this.similarList.brand[0].nameEn) {
  122. sType = 'brand'
  123. } else if (this.similarList.kind[0] && this.keyword === this.similarList.kind[0].nameCn) {
  124. sType = 'kind'
  125. } else if (this.similarList.component[0] && this.keyword === this.similarList.component[0].code) {
  126. sType = 'code'
  127. } else {
  128. let arr = [...this.similarList.store, ...this.similarList.brand, ...this.similarList.kind, ...this.similarList.component]
  129. if (arr[0]) {
  130. if (arr[0].name) {
  131. this.keyword = arr[0].name
  132. sType = 'store'
  133. } else if (arr[0].nameEn) {
  134. this.keyword = arr[0].nameEn
  135. sType = 'brand'
  136. } else if (arr[0].nameCn) {
  137. this.keyword = arr[0].nameCn
  138. sType = 'kind'
  139. } else if (arr[0].code) {
  140. this.keyword = arr[0].code
  141. sType = 'code'
  142. }
  143. }
  144. }
  145. }
  146. this.$emit('searchAction', {
  147. keyword: this.keyword,
  148. type: sType
  149. })
  150. }
  151. this.searchKeyword = this.keyword
  152. scrollTo('body', 10)
  153. this.showSimilarWord = false
  154. },
  155. onKeywordInput: function () {
  156. this.clickCount ++
  157. let count = this.clickCount
  158. let timer = setTimeout(() => {
  159. this.getSimilarList(count, timer)
  160. }, 300)
  161. },
  162. getSimilarList: function (clickCount, timer) {
  163. clearTimeout(timer)
  164. if (this.showSimilar && this.keyword && this.keyword !== '' && clickCount === this.clickCount) {
  165. this.$http.get(this.similarUrl, {params: {keyword: this.keyword}}).then(
  166. res => {
  167. this.similarList = res.data
  168. this.showSimilarWord = true
  169. }
  170. )
  171. }
  172. }
  173. }
  174. }
  175. </script>
  176. <style lang="scss" scoped>
  177. .mobile-search-header {
  178. &.search-content {
  179. color: #333;
  180. input {
  181. margin: 0 0 0 .5rem;
  182. line-height: normal;
  183. }
  184. ul {
  185. width: 6.48rem;
  186. background: #fff;
  187. position: absolute;
  188. left: .6rem;
  189. top: .72rem;
  190. border: 1px solid #ccc;
  191. border-radius: .05rem;
  192. max-height: 4.9rem;
  193. overflow-y: auto;
  194. li {
  195. height: .6rem;
  196. line-height: .6rem;
  197. padding: 0 .1rem;
  198. font-size: .26rem;
  199. &.title {
  200. color: #666;
  201. border-bottom: 1px solid #ddd;
  202. font-weight: bold;
  203. background: #f6f5f5;
  204. }
  205. }
  206. }
  207. }
  208. &.normal {
  209. position: relative;
  210. background: #f1f3f6;
  211. z-index: 1;
  212. input {
  213. border: 1px solid #3f84f6;
  214. width: 7.1rem;
  215. margin: 0 0 0 .1rem;
  216. }
  217. > a {
  218. display: none;
  219. }
  220. ul {
  221. width: 7.1rem;
  222. left: .19rem;
  223. }
  224. }
  225. }
  226. </style>