SearchHeader.vue 7.9 KB

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