search.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <template>
  2. <view class="search-container">
  3. <view class="search-header">
  4. <u-search placeholder="搜索感兴趣的直播/视频" v-model="keyword" :show-action="true" action-text="搜索" @custom="onSearch" @search="onSearch"></u-search>
  5. </view>
  6. <view class="content-box">
  7. <view class="section" v-if="historyList.length > 0 && !isSearching">
  8. <view class="section-header">
  9. <text class="title">历史搜索</text>
  10. <u-icon name="trash" size="20" color="#999" @click="clearHistory"></u-icon>
  11. </view>
  12. <view class="tag-wrap">
  13. <view class="tag-item" v-for="(item, index) in historyList" :key="index" @click="onTagClick(item)">{{item}}</view>
  14. </view>
  15. </view>
  16. <view class="section" v-if="!isSearching">
  17. <view class="section-header">
  18. <text class="title">热门搜索</text>
  19. </view>
  20. <view class="tag-wrap">
  21. <view class="tag-item hot" v-for="(item, index) in hotList" :key="index" @click="onTagClick(item)">{{item}}</view>
  22. </view>
  23. </view>
  24. <view class="result-list" v-if="isSearching">
  25. <view class="result-item" v-for="(item, index) in resultList" :key="index" @click="goDetail(item)">
  26. <view class="left-icon">
  27. <u-icon name="play-circle-fill" color="#2583EB" size="24"></u-icon>
  28. </view>
  29. <view class="info">
  30. <text class="name">{{item.title}}</text>
  31. <text class="desc">{{item.desc}}</text>
  32. </view>
  33. </view>
  34. <u-empty v-if="resultList.length === 0" mode="search" text="暂无搜索结果"></u-empty>
  35. </view>
  36. </view>
  37. </view>
  38. </template>
  39. <script>
  40. export default {
  41. data() {
  42. return {
  43. keyword: '',
  44. historyList: ['中医养生', '瑜伽入门', '糖尿病饮食'],
  45. hotList: ['高血压调理', '春季护肝', '八段锦教学', '名医讲座'],
  46. resultList: [],
  47. isSearching: false
  48. }
  49. },
  50. methods: {
  51. onSearch(val) {
  52. if (!val) return;
  53. this.keyword = val;
  54. this.isSearching = true;
  55. this.saveHistory(val);
  56. // Mock search logic
  57. setTimeout(() => {
  58. this.resultList = [
  59. { id: 1, title: val + ' - 相关直播回放', desc: '张医生讲解核心要点', type: 'video' },
  60. { id: 2, title: val + ' - 进阶课程', desc: '系统性学习方案', type: 'course' },
  61. { id: 3, title: '如何做好' + val, desc: '日常生活中需要注意的事项', type: 'article' }
  62. ];
  63. }, 500);
  64. },
  65. onTagClick(text) {
  66. this.keyword = text;
  67. this.onSearch(text);
  68. },
  69. clearHistory() {
  70. this.historyList = [];
  71. },
  72. saveHistory(val) {
  73. if (!this.historyList.includes(val)) {
  74. this.historyList.unshift(val);
  75. if (this.historyList.length > 10) this.historyList.pop();
  76. }
  77. },
  78. goDetail(item) {
  79. uni.navigateTo({
  80. url: '/pages/course/video/liveDetail?id=' + item.id
  81. });
  82. }
  83. }
  84. }
  85. </script>
  86. <style scoped lang="scss">
  87. .search-container {
  88. min-height: 100vh;
  89. background-color: #fff;
  90. }
  91. .search-header {
  92. padding: 20rpx 30rpx;
  93. background-color: #fff;
  94. border-bottom: 1rpx solid #f5f5f5;
  95. }
  96. .content-box {
  97. padding: 30rpx;
  98. }
  99. .section {
  100. margin-bottom: 40rpx;
  101. .section-header {
  102. display: flex;
  103. justify-content: space-between;
  104. align-items: center;
  105. margin-bottom: 20rpx;
  106. .title {
  107. font-size: 30rpx;
  108. font-weight: bold;
  109. color: #333;
  110. }
  111. }
  112. .tag-wrap {
  113. display: flex;
  114. flex-wrap: wrap;
  115. .tag-item {
  116. padding: 10rpx 24rpx;
  117. background-color: #f5f7fa;
  118. border-radius: 30rpx;
  119. font-size: 26rpx;
  120. color: #666;
  121. margin-right: 20rpx;
  122. margin-bottom: 20rpx;
  123. &.hot {
  124. color: #2583EB;
  125. background-color: rgba(37, 131, 235, 0.1);
  126. }
  127. }
  128. }
  129. }
  130. .result-list {
  131. .result-item {
  132. display: flex;
  133. padding: 20rpx 0;
  134. border-bottom: 1rpx solid #f9f9f9;
  135. .left-icon {
  136. margin-right: 20rpx;
  137. display: flex;
  138. align-items: center;
  139. }
  140. .info {
  141. flex: 1;
  142. display: flex;
  143. flex-direction: column;
  144. .name {
  145. font-size: 30rpx;
  146. color: #333;
  147. margin-bottom: 8rpx;
  148. }
  149. .desc {
  150. font-size: 24rpx;
  151. color: #999;
  152. }
  153. }
  154. }
  155. }
  156. </style>