SearchHeader.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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 && 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" v-if="similarType == 'all'">品牌</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" v-if="similarType == 'all'">物料名称</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" v-if="similarType == 'all'">型号</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: { // 提示keyword
  57. type: String,
  58. default: ''
  59. },
  60. similarType: { // 选择出现的联想词类型
  61. type: String,
  62. default: 'all'
  63. },
  64. useMatchRule: { // 使用既定的匹配规则
  65. type: Boolean,
  66. default: true
  67. },
  68. expandClass: {
  69. type: String,
  70. default: ''
  71. }
  72. },
  73. data () {
  74. return {
  75. keyword: '',
  76. similarList: {},
  77. showSimilarWord: false,
  78. searchKeyword: '',
  79. clickCount: 0
  80. }
  81. },
  82. watch: {
  83. outerKeyword: {
  84. handler: function (val) {
  85. this.keyword = val
  86. },
  87. immediate: true
  88. }
  89. },
  90. mounted () {
  91. this.$nextTick(() => {
  92. document.onclick = () => {
  93. this.showSimilarWord = false
  94. }
  95. })
  96. },
  97. computed: {
  98. emptyStatus () {
  99. let similarList = this.similarList
  100. if (this.type === 'supplier') {
  101. return (similarList.pCmpCode && similarList.pCmpCode.length) ||
  102. (similarList.pBrandEn && similarList.pBrandEn.length) ||
  103. (similarList.kind && similarList.kind.length)
  104. } else if (this.type === 'default') {
  105. return (similarList.component && similarList.component.length) ||
  106. (similarList.brand && similarList.brand.length) ||
  107. (similarList.kind && similarList.kind.length)
  108. }
  109. }
  110. },
  111. methods: {
  112. onSearch: function (key, type, e) {
  113. if (e) {
  114. e.stopPropagation()
  115. }
  116. // if (key === this.searchKeyword || this.keyword === this.searchKeyword) {
  117. // return
  118. // }
  119. if (key || !this.useMatchRule) {
  120. this.keyword = key || this.keyword
  121. this.$emit('searchAction', {
  122. keyword: this.keyword,
  123. type: type
  124. })
  125. } else {
  126. let sType = null
  127. if (this.type === 'default' && this.keyword && this.keyword !== '' && this.similarList.brand) { // 防止接口报错无法搜索
  128. if (this.similarList.brand[0] && this.keyword === this.similarList.brand[0].nameEn) {
  129. sType = 'brand'
  130. } else if (this.similarList.kind[0] && this.keyword === this.similarList.kind[0].nameCn) {
  131. sType = 'kind'
  132. } else if (this.similarList.component[0] && this.keyword === this.similarList.component[0].code) {
  133. sType = 'code'
  134. } else {
  135. let arr = [...this.similarList.brand, ...this.similarList.kind, ...this.similarList.component]
  136. if (arr[0]) {
  137. if (arr[0].nameEn) {
  138. this.keyword = arr[0].nameEn
  139. sType = 'brand'
  140. } else if (arr[0].nameCn) {
  141. this.keyword = arr[0].nameCn
  142. sType = 'kind'
  143. } else if (arr[0].code) {
  144. this.keyword = arr[0].code
  145. sType = 'code'
  146. }
  147. }
  148. }
  149. } else if (this.type === 'supplier' && this.keyword && this.keyword !== '' && this.similarList.pBrandEn) { // 防止接口报错无法搜索
  150. if (this.similarList.pBrandEn[0] && this.keyword === this.similarList.pBrandEn[0].nameEn) {
  151. sType = 'pBrandEn'
  152. } else if (this.similarList.kind[0] && this.keyword === this.similarList.kind[0].kind) {
  153. sType = 'kind'
  154. } else if (this.similarList.pCmpCode[0] && this.keyword === this.similarList.pCmpCode[0].pCmpCode) {
  155. sType = 'pCmpCode'
  156. } else {
  157. let arr = [...this.similarList.pBrandEn, ...this.similarList.kind, ...this.similarList.pCmpCode]
  158. if (arr[0]) {
  159. if (arr[0].nameEn) {
  160. this.keyword = arr[0].nameEn
  161. sType = 'pBrandEn'
  162. } else if (arr[0].kind) {
  163. this.keyword = arr[0].kind
  164. sType = 'kind'
  165. } else if (arr[0].pCmpCode) {
  166. this.keyword = arr[0].pCmpCode
  167. sType = 'pCmpCode'
  168. }
  169. }
  170. }
  171. }
  172. this.$emit('searchAction', {
  173. keyword: this.keyword,
  174. type: sType
  175. })
  176. }
  177. this.searchKeyword = this.keyword
  178. scrollTo('body', 10)
  179. this.showSimilarWord = false
  180. },
  181. onKeywordInput: function () {
  182. this.clickCount ++
  183. let count = this.clickCount
  184. let timer = setTimeout(() => {
  185. this.getSimilarList(count, timer)
  186. }, 300)
  187. },
  188. getSimilarList: function (clickCount, timer) {
  189. clearTimeout(timer)
  190. if (this.showSimilar && this.keyword && this.keyword !== '' && clickCount === this.clickCount) {
  191. this.$http.get(this.similarUrl, {params: {keyword: this.keyword}}).then(
  192. res => {
  193. this.similarList = res.data
  194. this.showSimilarWord = true
  195. }
  196. )
  197. }
  198. }
  199. }
  200. }
  201. </script>
  202. <style lang="scss" scoped>
  203. .mobile-search-header {
  204. &.search-content {
  205. color: #333;
  206. input {
  207. margin: 0 0 0 .5rem;
  208. line-height: normal;
  209. }
  210. ul {
  211. width: 6.48rem;
  212. background: #fff;
  213. position: absolute;
  214. left: .6rem;
  215. top: .72rem;
  216. border: 1px solid #ccc;
  217. border-radius: .05rem;
  218. max-height: 4.5rem;
  219. overflow-y: auto;
  220. li {
  221. height: .6rem;
  222. line-height: .6rem;
  223. padding: 0 .1rem;
  224. font-size: .26rem;
  225. &.title {
  226. color: #666;
  227. border-bottom: 1px solid #ddd;
  228. font-weight: bold;
  229. background: #f6f5f5;
  230. }
  231. }
  232. }
  233. }
  234. &.normal {
  235. position: relative;
  236. background: #f1f3f6;
  237. z-index: 1;
  238. input {
  239. border: 1px solid #3f84f6;
  240. width: 7.1rem;
  241. margin: 0 0 0 .1rem;
  242. }
  243. > a {
  244. display: none;
  245. }
  246. ul {
  247. width: 7.1rem;
  248. left: .19rem;
  249. }
  250. }
  251. }
  252. </style>