SearchHeader.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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 && (similarType == 'all' || similarType == 'brand')">
  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 && (similarType == 'all' || similarType == 'kind')">
  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 && (similarType == 'all' || similarType == 'code')">
  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. similarType: {
  61. type: String,
  62. default: 'all'
  63. }
  64. },
  65. data () {
  66. return {
  67. keyword: '',
  68. similarList: {},
  69. showSimilarWord: false,
  70. searchKeyword: '',
  71. clickCount: 0
  72. }
  73. },
  74. watch: {
  75. outerKeyword: {
  76. handler: function (val) {
  77. this.keyword = val
  78. },
  79. immediate: true
  80. }
  81. },
  82. mounted () {
  83. this.$nextTick(() => {
  84. document.onclick = () => {
  85. this.showSimilarWord = false
  86. }
  87. })
  88. },
  89. computed: {
  90. emptyStatus () {
  91. let similarList = this.similarList
  92. if (this.type === 'supplier') {
  93. return (similarList.pCmpCode && similarList.pCmpCode.length) ||
  94. (similarList.pBrandEn && similarList.pBrandEn.length) ||
  95. (similarList.kind && similarList.kind.length)
  96. } else if (this.type === 'default') {
  97. return (similarList.component && similarList.component.length) ||
  98. (similarList.brand && similarList.brand.length) ||
  99. (similarList.kind && similarList.kind.length)
  100. }
  101. }
  102. },
  103. methods: {
  104. onSearch: function (key, type, e) {
  105. if (e) {
  106. e.stopPropagation()
  107. }
  108. // if (key === this.searchKeyword || this.keyword === this.searchKeyword) {
  109. // return
  110. // }
  111. if (key) {
  112. this.keyword = key
  113. this.$emit('searchAction', {
  114. keyword: this.keyword,
  115. type: type
  116. })
  117. } else {
  118. let sType = null
  119. if (this.type === 'default' && this.keyword && this.keyword !== '' && this.similarList.component) {
  120. if (this.similarList.component[0] && this.keyword === this.similarList.component[0].code) {
  121. sType = 'code'
  122. } else if (this.similarList.brand[0] && this.keyword === this.similarList.brand[0].nameEn) {
  123. sType = 'brand'
  124. } else if (this.similarList.kind[0] && this.keyword === this.similarList.kind[0].nameCn) {
  125. sType = 'kind'
  126. } else {
  127. let arr = [...this.similarList.component, ...this.similarList.brand, ...this.similarList.kind]
  128. if (arr[0]) {
  129. if (arr[0].code) {
  130. this.keyword = arr[0].code
  131. sType = 'code'
  132. } else if (arr[0].nameEn) {
  133. this.keyword = arr[0].nameEn
  134. sType = 'brand'
  135. } else if (arr[0].nameCn) {
  136. this.keyword = arr[0].nameCn
  137. sType = 'kind'
  138. }
  139. }
  140. }
  141. } else if (this.type === 'supplier' && this.keyword && this.keyword !== '' && this.similarList.pCmpCode) {
  142. if (this.similarList.pCmpCode[0] && this.keyword === this.similarList.pCmpCode[0].pCmpCode) {
  143. sType = 'pCmpCode'
  144. } else if (this.similarList.pBrandEn[0] && this.keyword === this.similarList.pBrandEn[0].nameEn) {
  145. sType = 'pBrandEn'
  146. } else if (this.similarList.kind[0] && this.keyword === this.similarList.kind[0].kind) {
  147. sType = 'kind'
  148. } else {
  149. let arr = [...this.similarList.pCmpCode, ...this.similarList.pBrandEn, ...this.similarList.kind]
  150. if (arr[0]) {
  151. if (arr[0].pCmpCode) {
  152. this.keyword = arr[0].pCmpCode
  153. sType = 'pCmpCode'
  154. } else if (arr[0].nameEn) {
  155. this.keyword = arr[0].nameEn
  156. sType = 'pBrandEn'
  157. } else if (arr[0].kind) {
  158. this.keyword = arr[0].kind
  159. sType = 'kind'
  160. }
  161. }
  162. }
  163. }
  164. this.$emit('searchAction', {
  165. keyword: this.keyword,
  166. type: sType
  167. })
  168. }
  169. this.searchKeyword = this.keyword
  170. scrollTo('body', 10)
  171. this.showSimilarWord = false
  172. },
  173. onKeywordInput: function () {
  174. this.clickCount ++
  175. let count = this.clickCount
  176. let timer = setTimeout(() => {
  177. this.getSimilarList(count, timer)
  178. }, 300)
  179. },
  180. getSimilarList: function (clickCount, timer) {
  181. clearTimeout(timer)
  182. if (this.showSimilar && this.keyword && this.keyword !== '' && clickCount === this.clickCount) {
  183. this.$http.get(this.similarUrl, {params: {keyword: this.keyword}}).then(
  184. res => {
  185. this.similarList = res.data
  186. this.showSimilarWord = true
  187. }
  188. )
  189. }
  190. }
  191. }
  192. }
  193. </script>
  194. <style lang="scss" scoped>
  195. .search-content {
  196. color: #333;
  197. input {
  198. margin: 0 0 0 .5rem;
  199. line-height: normal;
  200. }
  201. ul {
  202. width: 6.48rem;
  203. background: #fff;
  204. position: absolute;
  205. left: .6rem;
  206. top: .72rem;
  207. border: 1px solid #ccc;
  208. border-radius: .05rem;
  209. max-height: 4.5rem;
  210. overflow-y: auto;
  211. li {
  212. height: .6rem;
  213. line-height: .6rem;
  214. padding: 0 .1rem;
  215. font-size: .26rem;
  216. &.title {
  217. color: #666;
  218. border-bottom: 1px solid #ddd;
  219. font-weight: bold;
  220. background: #f6f5f5;
  221. }
  222. }
  223. }
  224. }
  225. </style>