HotspotList.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <template>
  2. <div
  3. class="hotspot-list"
  4. >
  5. <div class="top-bar">
  6. <button
  7. class="back"
  8. @click="$emit('back')"
  9. >
  10. <img
  11. src="@/assets/images/swkk/back-simple.png"
  12. alt=""
  13. draggable="false"
  14. >
  15. </button>
  16. <div class="search-wrap">
  17. <input
  18. v-model.trim="keyword"
  19. maxlength="30"
  20. type="text"
  21. placeholder="请输入关键字"
  22. @keydown.enter="onClickSearch"
  23. >
  24. <button
  25. class="search"
  26. @click="onClickSearch"
  27. >
  28. 搜索
  29. </button>
  30. </div>
  31. </div>
  32. <div
  33. v-if="historyList.length"
  34. class="search-history"
  35. >
  36. <div class="title-bar">
  37. <h2>历史搜索</h2>
  38. <button
  39. class="clear"
  40. @click="onClickDelete"
  41. >
  42. <img
  43. src="@/assets/images/swkk/delete.png"
  44. alt=""
  45. draggable="false"
  46. >
  47. </button>
  48. </div>
  49. <ul class="history-list">
  50. <li
  51. v-for="(item, index) in historyList"
  52. :key="index"
  53. @click="onClickHistoryItem(item)"
  54. >
  55. {{ item }}
  56. </li>
  57. </ul>
  58. </div>
  59. <ul class="search-result">
  60. <li
  61. v-for="(item, index) in resultList"
  62. :key="index"
  63. @click="$emit('click-hotspot', item)"
  64. v-html="highlightKeyword(item.title.split('&')[0])"
  65. />
  66. <div
  67. v-if="!resultList.length"
  68. class="no-data"
  69. >
  70. <img
  71. src="@/assets/images/swkk/no-data-gray.png"
  72. alt=""
  73. draggable="false"
  74. >
  75. <div class="text">
  76. 暂无内容
  77. </div>
  78. </div>
  79. </ul>
  80. </div>
  81. </template>
  82. <script>
  83. export default {
  84. props: {
  85. hotspotData: {
  86. type: Array,
  87. required: true,
  88. },
  89. },
  90. data() {
  91. return {
  92. keyword: '',
  93. historyList: [],
  94. resultList: [],
  95. }
  96. },
  97. computed: {
  98. hotspotsCombiled() {
  99. return this.hotspotData.filter(v => v.title.split("&")[2] || !v.title.includes("&"))
  100. },
  101. },
  102. mounted() {
  103. this.historyList = JSON.parse(localStorage.getItem('hotspot-search-history')) || []
  104. this.onClickSearch()
  105. },
  106. destroyed() {
  107. localStorage.setItem('hotspot-search-history', JSON.stringify(this.historyList))
  108. },
  109. methods: {
  110. onClickSearch() {
  111. if (this.keyword && !this.historyList.includes(this.keyword)) {
  112. this.historyList.unshift(this.keyword)
  113. if (this.keyword.length === 31) {
  114. this.keyword.pop()
  115. }
  116. }
  117. this.resultList = this.hotspotsCombiled.filter(v => v.title.split("&")[0].includes(this.keyword))
  118. },
  119. onClickDelete() {
  120. this.historyList = []
  121. },
  122. onClickHistoryItem(historyItem) {
  123. this.keyword = historyItem
  124. this.onClickSearch()
  125. },
  126. highlightKeyword(title) {
  127. if (this.keyword) {
  128. const reg = new RegExp(`(${this.keyword})`, 'gi')
  129. const replace = '<span style="color:#930909;">$1</span>'
  130. return title.replace(reg, replace)
  131. } else {
  132. return title
  133. }
  134. }
  135. }
  136. }
  137. </script>
  138. <style lang="less" scoped>
  139. .hotspot-list {
  140. position: absolute;
  141. top: 0;
  142. left: 0;
  143. width: 100%;
  144. height: 100%;
  145. background: rgba(255,251,245,0.9);
  146. backdrop-filter: blur(4px);
  147. display: flex;
  148. flex-direction: column;
  149. > .top-bar {
  150. flex: 0 0 auto;
  151. margin-top: 3.67rem;
  152. margin-left: 0.33rem;
  153. margin-right: 1.33rem;
  154. display: flex;
  155. align-items: center;
  156. > button.back {
  157. width: 1.08rem;
  158. height: 2.46rem;
  159. box-sizing: content-box;
  160. padding: 1rem;
  161. flex: 0 0 auto;
  162. > img {
  163. width: 100%;
  164. height: 100%;
  165. }
  166. }
  167. > .search-wrap {
  168. margin-left: 0.71rem;
  169. height: 5rem;
  170. flex: 1 0 1px;
  171. background: #FFFFFF;
  172. border-radius: 4.17rem 4.17rem 4.17rem 4.17rem;
  173. border: 0.08rem solid #930909;
  174. display: flex;
  175. padding: 0.54rem 0.54rem 0.54rem 1.21rem;
  176. > input {
  177. flex: 1 0 1px;
  178. height: 100%;
  179. color: #666666;
  180. font-size: 1.67rem;
  181. }
  182. > button.search {
  183. height: 100%;
  184. width: 8.33rem;
  185. font-size: 1.67rem;
  186. color: #D8B275;
  187. background: #930909;
  188. border-radius: 2.08rem 2.08rem 2.08rem 2.08rem;
  189. margin-left: 0.54rem;
  190. }
  191. }
  192. }
  193. > .search-history {
  194. flex: 0 0 auto;
  195. margin-top: 2.92rem;
  196. margin-left: 2.5rem;
  197. margin-right: 2.5rem;
  198. > .title-bar {
  199. display: flex;
  200. align-items: center;
  201. justify-content: space-between;
  202. > h2 {
  203. font-size: 1.83rem;
  204. font-weight: bold;
  205. color: #333333;
  206. }
  207. > button.clear {
  208. width: 2.08rem;
  209. height: 2.15rem;
  210. > img {
  211. width: 100%;
  212. height: 100%;
  213. }
  214. }
  215. }
  216. > .history-list {
  217. margin-top: 1.46rem;
  218. display: flex;
  219. flex-wrap: wrap;
  220. margin-right: -1.25rem;
  221. > li {
  222. height: 3.33rem;
  223. line-height: 3.33rem;
  224. background-color: #fff;
  225. border-radius: 1.67rem;
  226. padding: 0 1.71rem;
  227. display: inline-block;
  228. margin-right: 1.25rem;
  229. margin-bottom: 1rem;
  230. font-size: 1.5rem;
  231. color: #666666;
  232. max-width: 20rem;
  233. overflow: hidden;
  234. white-space: nowrap;
  235. text-overflow: ellipsis;
  236. }
  237. }
  238. }
  239. > .search-result {
  240. flex: 1 0 1px;
  241. margin-top: 1.92rem;
  242. margin-left: 2.5rem;
  243. margin-right: 2.5rem;
  244. overflow: auto;
  245. position: relative;
  246. > li {
  247. display: block;
  248. color: #666666;
  249. font-size: 1.67rem;
  250. padding: 1em 0;
  251. overflow: hidden;
  252. white-space: nowrap;
  253. text-overflow: ellipsis;
  254. }
  255. > .no-data {
  256. position: absolute;
  257. top: 40%;
  258. left: 50%;
  259. transform: translate(-50%, -50%);
  260. text-align: center;
  261. > img {
  262. width: 18.21rem;
  263. height: 16.54rem;
  264. }
  265. > .text {
  266. margin-top: 1.88rem;
  267. font-size: 1.83rem;
  268. color: #666666;
  269. }
  270. }
  271. }
  272. }
  273. </style>