图书馆小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
7.5 KiB

1 week ago
  1. <template>
  2. <view class="collection-page">
  3. <view class="tab-box">
  4. <view class="tab-item" :class="activeTab === 1 ? 'active' : ''" @click="switchTab(1)"> 图书 </view>
  5. <view class="tab-item" :class="activeTab === 2 ? 'active' : ''" @click="switchTab(2)"> 活动 </view>
  6. </view>
  7. <!-- 内容区域 -->
  8. <view class="content-box">
  9. <!-- 图书收藏 -->
  10. <view v-if="activeTab === 1" class="tab-content">
  11. <view class="empty" v-if="bookCollectList.length === 0">
  12. 暂无收藏的图书
  13. </view>
  14. <view class="recommendation-list" v-else>
  15. <view
  16. class="book-item"
  17. v-for="(item, index) in bookCollectList"
  18. @click="goToBookDetail(item)"
  19. :key="index"
  20. >
  21. <image class="book-cover" :src="item.cover"></image>
  22. <view class="book-title">{{ item.title }}</view>
  23. </view>
  24. </view>
  25. <uni-load-more status="loading" v-if="isLoading"></uni-load-more>
  26. <view class="no-more" v-if="noMore && bookCollectList.length > 0">
  27. 没有更多数据了
  28. </view>
  29. </view>
  30. <!-- 活动收藏 -->
  31. <view v-if="activeTab === 2" class="tab-content">
  32. <view class="empty" v-if="activityCollectList.length === 0">
  33. 暂无收藏的活动
  34. </view>
  35. <view class="activity-list" v-else>
  36. <view
  37. class="activity-item"
  38. v-for="(item, index) in activityCollectList"
  39. @click="toActivityDetail(item)"
  40. :key="index"
  41. >
  42. <image class="activity-img" :src="item.imgUrl"></image>
  43. <view class="activity-info">
  44. <view class="activity-info-left">
  45. <text class="title">{{ item.title }}</text>
  46. <view class="time">
  47. <uni-icons class="time-icon" type="time" size="15"></uni-icons>
  48. <text>{{ item.time }}</text>
  49. </view>
  50. </view>
  51. <button
  52. class="activity-btn"
  53. :class="item.status === 0 ? 'disabled-btn' : ''"
  54. type="primary"
  55. :disabled="item.status === 0"
  56. >
  57. {{ item.status === 1 ? '立即参加' : '活动结束' }}
  58. </button>
  59. </view>
  60. </view>
  61. </view>
  62. <uni-load-more status="loading" v-if="isLoading"></uni-load-more>
  63. <view class="no-more" v-if="noMore && activityCollectList.length > 0">
  64. 没有更多数据了
  65. </view>
  66. </view>
  67. </view>
  68. </view>
  69. </template>
  70. <script>
  71. export default {
  72. data() {
  73. return {
  74. activeTab: 1,
  75. isLoading: false,
  76. noMore: false,
  77. pageNum: 1,
  78. pageSize: 5,
  79. bookCollectList: [
  80. { isbn: '9787544741110', title: '人工智能基础——数学知识', cover: 'https://qiniu.aiyxlib.com/1606124577077' },
  81. { isbn: '9787539938032', title: 'Vim 8文本处理实战', cover: 'https://qiniu.aiyxlib.com/1606178450151' },
  82. { isbn: '9787536692930', title: 'Oracle从入门到精通', cover: 'https://qiniu.aiyxlib.com/1606123986028' }
  83. ],
  84. allActivityList: [
  85. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '读书分享会', time: "2025-11-03 ~2025-11-09", status: 1 },
  86. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '作者见面会', time: "2025-11-03 ~2025-11-09", status: 0 },
  87. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '新书签售会', time: "2025-11-05 ~2025-11-10", status: 1 },
  88. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '文学讲座', time: "2025-11-06 ~2025-11-12", status: 1 },
  89. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '亲子阅读日', time: "2025-11-07 ~2025-11-13", status: 1 },
  90. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '书法展览', time: "2025-11-08 ~2025-11-14", status: 1 },
  91. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '诗词大会', time: "2025-11-09 ~2025-11-15", status: 0 },
  92. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '绘本故事', time: "2025-11-10 ~2025-11-16", status: 1 },
  93. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '读书打卡', time: "2025-11-11 ~2025-11-17", status: 1 },
  94. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '作家访谈', time: "2025-11-12 ~2025-11-18", status: 1 },
  95. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '文化沙龙', time: "2025-11-13 ~2025-11-19", status: 1 },
  96. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '手工创作', time: "2025-11-14 ~2025-11-20", status: 0 },
  97. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '经典诵读', time: "2025-11-15 ~2025-11-21", status: 1 },
  98. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '图书交换', time: "2025-11-16 ~2025-11-22", status: 1 },
  99. { imgUrl: "https://qiniu.aiyxlib.com/1605060269830", title: '阅读竞赛', time: "2025-11-17 ~2025-11-23", status: 1 },
  100. ],
  101. activityCollectList: [],
  102. }
  103. },
  104. onLoad() {
  105. this.initActivityList() // 只初始化一次活动列表
  106. },
  107. onPullDownRefresh() {
  108. this.refreshData()
  109. },
  110. onReachBottom() {
  111. if (this.noMore || this.isLoading) return
  112. this.loadMore() // 这里只调用“追加”,不刷新
  113. },
  114. methods: {
  115. switchTab(tab) {
  116. this.activeTab = tab
  117. // 切Tab不重置活动列表,避免闪屏
  118. },
  119. // 初始化第一页(进入页面/下拉刷新用)
  120. initActivityList() {
  121. this.pageNum = 1
  122. this.noMore = false
  123. this.activityCollectList = this.allActivityList.slice(0, this.pageSize)
  124. this.noMore = this.allActivityList.length <= this.pageSize
  125. },
  126. refreshData() {
  127. this.isLoading = true
  128. setTimeout(() => {
  129. // 图书重置
  130. this.bookCollectList = [
  131. { isbn: '9787544741110', title: '人工智能基础——数学知识', cover: 'https://qiniu.aiyxlib.com/1606124577077' },
  132. { isbn: '9787539938032', title: 'Vim 8文本处理实战', cover: 'https://qiniu.aiyxlib.com/1606178450151' },
  133. { isbn: '9787536692930', title: 'Oracle从入门到精通', cover: 'https://qiniu.aiyxlib.com/1606123986028' }
  134. ]
  135. // 活动回到第一页
  136. this.initActivityList()
  137. this.isLoading = false
  138. uni.stopPullDownRefresh()
  139. }, 500)
  140. },
  141. // 上拉加载
  142. loadMore() {
  143. this.isLoading = true
  144. this.pageNum++
  145. setTimeout(() => {
  146. const start = (this.pageNum - 1) * this.pageSize
  147. const end = this.pageNum * this.pageSize
  148. const newArr = this.allActivityList.slice(start, end)
  149. if (newArr.length) {
  150. this.activityCollectList = [...this.activityCollectList, ...newArr]
  151. }
  152. this.noMore = this.allActivityList.length <= end
  153. this.isLoading = false
  154. }, 500)
  155. },
  156. goToBookDetail(item) {
  157. uni.navigateTo({ url: "/subpkg/pages/book-detail/book-detail?isbn=" + item.isbn })
  158. },
  159. toActivityDetail(item) {
  160. uni.navigateTo({ url: "/subpkg/pages/activity-detail/activity-detail?title=" + item.title })
  161. },
  162. },
  163. }
  164. </script>
  165. <style lang="scss" scoped>
  166. .collection-page {
  167. background-color: #f7f8fa;
  168. min-height: 100vh;
  169. }
  170. .tab-box {
  171. display: flex;
  172. background-color: #fff;
  173. margin-bottom: 10px;
  174. position: sticky;
  175. top: 0;
  176. z-index: 99;
  177. }
  178. .tab-item {
  179. flex: 1;
  180. text-align: center;
  181. padding: 10px 0;
  182. font-size: 15px;
  183. color: #333;
  184. position: relative;
  185. }
  186. .tab-item.active {
  187. color: #01a4fe;
  188. font-weight: bold;
  189. }
  190. .tab-item.active::after {
  191. content: '';
  192. position: absolute;
  193. width: 25px;
  194. height: 2px;
  195. background-color: #01a4fe;
  196. bottom: 0;
  197. left: 50%;
  198. transform: translateX(-50%);
  199. border-radius: 2px;
  200. }
  201. .content-box {
  202. padding: 0 10px;
  203. }
  204. .tab-content {
  205. padding-top: 10px;
  206. }
  207. .empty {
  208. text-align: center;
  209. padding: 60px 0;
  210. color: #999;
  211. font-size: 14px;
  212. }
  213. .no-more {
  214. text-align: center;
  215. padding: 20px 0;
  216. color: #999;
  217. font-size: 13px;
  218. }
  219. .recommendation-list{
  220. flex-wrap: wrap;
  221. .book-item {
  222. margin-bottom: 16px;
  223. }
  224. }
  225. </style>