index-commu.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <template>
  2. <view class="index-commu" :style="{ height: screenHeight - tabbarHeight - statusbarHeight + 'px', zIndex: SHOW ? '1' : '-1' }">
  3. <custom-nav :title="logged ? '' : '社区'" noback ref="ltm" />
  4. <view class="status_bar"> <!-- 这里是状态栏 --> </view>
  5. <view v-if="logged" class="content">
  6. <view class="swiper-nav">
  7. <view v-for="(item, index) in typeList" :key="index" class="item" :class="{ active: MIXIN_ActiveIndex === index }" @tap="switchSwiper(index)">{{ item }}</view>
  8. <view class="moveBar" :style="{ left: MIXIN_MoveBarLeft + 'px', width: 100 / typeList.length + '%' }"><text></text></view>
  9. </view>
  10. <view class="swiper-area">
  11. <pulldown-refresher ref="pulldownRefresher" @pulldownRefresh="MIXIN_pulldownrefresh">
  12. <swiper class="swiper" :current="MIXIN_NowIndex" :duration="234" @transition="MIXIN_transition" @change="MIXIN_change" @animationfinish="MIXIN_animationfinish">
  13. <swiper-item v-for="(item, listsIndex) in typeList" :key="listsIndex">
  14. <scroll-view scroll-y :style="{ height: MIXIN_ScrollViewHeight + 'px' }" @scrolltolower="MIXIN_scrolltolower">
  15. <view class="commu-item" v-for="(commuItem, commuIndex) in lists[listsIndex]" :key="commuIndex">
  16. <view class="article-header">
  17. <image class="head-pic" :src="commuItem.avatar"></image>
  18. <view class="name">
  19. <text>{{ commuItem.user_name }}</text>
  20. <text v-if="commuItem.identity === 1" class="identity">官方</text>
  21. </view>
  22. <text class="time">{{ commuItem.time | DistanceNow }}</text>
  23. </view>
  24. <navigator :url="'../../pages/article-detail/article-detail?type=' + listsIndex + '&index=' + commuIndex "
  25. v-if="commuItem.type === 1" class="body type-article"
  26. >
  27. <view class="title ellipsis">{{ commuItem.title }}</view>
  28. <view class="des">{{ commuItem.des + '...' }}</view>
  29. <commu-article-imgs :article="commuItem.content" />
  30. </navigator>
  31. <navigator :url="'../../pages/article-detail/article-detail?type=' + listsIndex + '&index=' + commuIndex "
  32. v-else class="body type-video"
  33. >
  34. <view class="des">{{ commuItem.title }}</view>
  35. <view class="video-player">
  36. <text class="cuIcon-video"></text>
  37. <image :src="commuItem.poster" mode="center"></image>
  38. </view>
  39. </navigator>
  40. <view class="article-footer">
  41. <view class="footer-item" @tap="thumbs(listsIndex, commuIndex)">
  42. <text v-if="!commuItem.thumbs" class="cuIcon-appreciate icon-right left"></text>
  43. <text v-else class="cuIcon-appreciatefill icon-right left fill"></text>
  44. <text>点赞</text>
  45. </view>
  46. <view class="footer-item center" @tap="like(listsIndex, commuIndex)">
  47. <text v-if="!commuItem.liked" class="cuIcon-like icon-right"></text>
  48. <text v-else class="cuIcon-likefill icon-right fill"></text>
  49. <text>收藏</text>
  50. </view>
  51. <view class="footer-item" @tap="share">
  52. <text class="cuIcon-forward icon-right right"></text>
  53. <text>分享</text>
  54. </view>
  55. </view>
  56. </view>
  57. <custom-reach-bottom v-if="lists[listsIndex].length" :nomore="page[listsIndex] === 0" />
  58. <swiper-status v-else :page="page[listsIndex]" />
  59. </scroll-view>
  60. </swiper-item>
  61. </swiper>
  62. </pulldown-refresher>
  63. </view>
  64. </view>
  65. <view v-else class="login-btn" style="height: 100%;">
  66. <navigator url="../../pages/login-reg/login-reg">登录/注册</navigator>
  67. </view>
  68. </view>
  69. </template>
  70. <script>
  71. import MIXIN from '@/mixin/swiper-list.js'
  72. import swiperStatus from '@/components/public/swiper-status.vue'
  73. import commuArticleImgs from '@/components/public/commu-article-imgs.vue'
  74. import pulldownRefresher from '@/components/public/pulldown-refresher.vue'
  75. import customReachBottom from '@/components/public/custom-reach-bottom.vue'
  76. import { commuRecommend, commuNewest, commuChanglai, commuCollect } from '@/apis/index/commu.js'
  77. export default {
  78. mixins: [MIXIN],
  79. components: { swiperStatus, customReachBottom, pulldownRefresher, commuArticleImgs },
  80. data() {
  81. return {
  82. title: '社区',
  83. page: [1, 1, 1, 1], // 每种类型的页数 当页数为零时表示当前类型没有更多了
  84. tabbarHeight: uni.upx2px(98), // tabbar 高度
  85. lists: { 0: [], 1: [], 2: [], 3: [] }, // 数据
  86. typeList: ['热门推荐', '最新更新', '常来微聊', '我的收藏'],
  87. apis: [commuRecommend, commuNewest, commuChanglai, commuCollect]
  88. }
  89. },
  90. computed: {
  91. screenHeight() { return this.$store.state.device.screenHeight },
  92. SHOW() { return this.$store.state.app.index_tabbar_index === 2 },
  93. statusbarHeight() { return this.$store.state.device.statusbarHeight },
  94. logged() { return this.$store.state.app.token.length === 0 ? false : true }
  95. },
  96. methods: {
  97. thumbs(listsIndex, commuIndex) {
  98. this.lists[listsIndex][commuIndex].thumbs = !this.lists[listsIndex][commuIndex].thumbs
  99. },
  100. like(listsIndex, commuIndex) {
  101. this.lists[listsIndex][commuIndex].liked = !this.lists[listsIndex][commuIndex].liked
  102. },
  103. share() {
  104. }
  105. },
  106. watch: {
  107. SHOW: {
  108. handler(val) {
  109. if (val) {
  110. if (!this.MIXIN_ScrollViewHeight) { // 如果 scrollvie 没有高度 就给它高度
  111. setTimeout(() => this.$offset('.swiper-area').then(res => this.MIXIN_ScrollViewHeight = res.height))
  112. }
  113. if (this.logged && !this.lists[this.MIXIN_NowIndex].length && this.page[this.MIXIN_NowIndex] !== 0) { // 当当前类型数量为 0 且有不是 没有更多时请求列表
  114. this.MIXIN_request()
  115. }
  116. }
  117. },
  118. immediate: true
  119. },
  120. lists: {
  121. handler(n) {
  122. this.$store.commit('article/UPDATA', n)
  123. },
  124. deep: true,
  125. immediate: true
  126. }
  127. }
  128. }
  129. </script>
  130. <style lang="scss" scoped>
  131. .index-commu {
  132. @include page();
  133. top: 0;
  134. left: 0;
  135. width: 100%;
  136. position: fixed;
  137. border-top-width: 0;
  138. .status_bar {
  139. width: 100%;
  140. background: $app-base-color;
  141. height: var(--status-bar-height);
  142. }
  143. .content {
  144. @include flex(column);
  145. .swiper-nav {
  146. text {
  147. width: 100rpx;
  148. }
  149. }
  150. .swiper-area {
  151. scroll-view {
  152. .commu-item {
  153. padding: 0 30rpx;
  154. margin-top: 10rpx;
  155. background: #FFFFFF;
  156. box-sizing: border-box;
  157. .body {
  158. &.type-article {
  159. .title {
  160. font-size: 32rpx;
  161. margin-top: 10rpx;
  162. line-height: 36rpx;
  163. }
  164. .des {
  165. font-size: 26rpx;
  166. margin-top: 10rpx;
  167. line-height: 36rpx;
  168. color: $app-sec-text-color;
  169. }
  170. }
  171. &.type-video {
  172. .des {
  173. margin-top: 10rpx;
  174. font-size: 26rpx;
  175. line-height: 36rpx;
  176. }
  177. .video-player {
  178. @include flex();
  179. height: 280rpx;
  180. overflow: hidden;
  181. margin-top: 10rpx;
  182. position: relative;
  183. border-radius: 10rpx;
  184. .cuIcon-video {
  185. top: 50%;
  186. left: 50%;
  187. z-index: 1;
  188. color: #FFFFFF;
  189. font-size: 98rpx;
  190. position: absolute;
  191. transform: translate(-50%, -50%);
  192. }
  193. image {
  194. top: 0;
  195. left: 0;
  196. width: 100%;
  197. height: 100%;
  198. position: absolute;
  199. }
  200. }
  201. }
  202. }
  203. }
  204. }
  205. }
  206. }
  207. }
  208. </style>