topic.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <template>
  2. <u-popup v-model="show" mode="bottom" closeable border-radius="14" safe-area-inset-bottom :duration="100">
  3. <view class="content-wrapper">
  4. <!-- 头部 -->
  5. <u-sticky>
  6. <view class="sticky">
  7. <view class="sticky-title xl normal bold">话题</view>
  8. <u-search :hideRight="true" :show-action="true" action-text="取消" :animation="true" @focus="hideRight=false"
  9. @blur="hideRight=true" @custom="handleCancel" placeholder="请输入搜索内容" height="64" @change="mescroll.resetUpScroll()"
  10. v-model="keyword"></u-search>
  11. </view>
  12. </u-sticky>
  13. <!-- 内容 -->
  14. <view class="container">
  15. <!-- 左侧菜单 -->
  16. <scroll-view scroll-y="true" class="left-menu">
  17. <block v-for="(menuItem, menuIndex) in topicData" :key="menuIndex">
  18. <view class="submenu normal" :class="{'active': menuIndex === menuCurrentIndex}" @click="selectMenu(menuIndex)">{{ menuItem.name }}</view>
  19. </block>
  20. </scroll-view>
  21. <!-- 右侧内容 -->
  22. <view class="right-content">
  23. <mescroll-uni ref="mescrollRef" top="0" height="712rpx" bgColor="#f5f5f5" @init="mescrollInit" @down="downCallback"
  24. @up="upCallback" :down="downOption" :up="upOption">
  25. <view class="tags">
  26. <view class="tags-item flex" @click="unSelectTopic">
  27. <u-image width="120" height="120" :src="'/bundle_b/static/icon_unselect_tags.png'" borderRadius="50%"></u-image>
  28. <text class="m-l-16 nr bold normal">不添加任何话题</text>
  29. </view>
  30. <template v-if="topicData[menuCurrentIndex]">
  31. <block v-for="(topicItem, topicIndex) in topicData[menuCurrentIndex].topic" :key="topicIndex">
  32. <view class="tags-item flex" @click="selectTopic(topicItem)">
  33. <image :src="topicItem.image" mode="aspectFill"></image>
  34. <view class="m-l-16">
  35. <view class="nr bold normal">{{ topicItem.name }}</view>
  36. <view class="m-t-10 xxs muted">{{ topicItem.click }}人在看</view>
  37. </view>
  38. </view>
  39. </block>
  40. </template>
  41. </view>
  42. </mescroll-uni>
  43. </view>
  44. </view>
  45. </view>
  46. </u-popup>
  47. </template>
  48. <script>
  49. import { getCommunityTopicLists } from "@/api/community.js"
  50. import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
  51. import MescrollMoreItemMixin from "@/components/mescroll-uni/mixins/mescroll-more-item.js";
  52. export default {
  53. mixins: [MescrollMixin, MescrollMoreItemMixin],
  54. name: "topic",
  55. props: {
  56. value: {
  57. type: Boolean
  58. },
  59. },
  60. data() {
  61. return {
  62. keyword: '',
  63. hideRight: true,
  64. menuCurrentIndex: 0,
  65. topicData: []
  66. }
  67. },
  68. computed: {
  69. // 弹窗Popup显示状态
  70. show: {
  71. get: function() {
  72. return this.value
  73. },
  74. set: function(value) {
  75. // #ifdef H5
  76. this.$nextTick(() => {
  77. this.mescroll.resetUpScroll()
  78. })
  79. // #endif
  80. this.$emit('input', value)
  81. }
  82. }
  83. },
  84. methods: {
  85. handleCancel() {
  86. this.keyword = '';
  87. this.mescroll.resetUpScroll()
  88. },
  89. // 选择菜单
  90. selectMenu(index) {
  91. this.menuCurrentIndex = index
  92. },
  93. // 选择话题
  94. selectTopic(item) {
  95. this.$emit('input', false)
  96. this.$emit('change', item)
  97. },
  98. // 不选择话题
  99. unSelectTopic() {
  100. this.$emit('input', false)
  101. this.$emit('change', '')
  102. },
  103. // 获取
  104. async upCallback(page) {
  105. getCommunityTopicLists({
  106. name: this.keyword,
  107. }).then(res => {
  108. this.topicData = res.data
  109. this.mescroll.endSuccess(10, 0);
  110. }).catch((err) => {
  111. this.mescroll.endErr()
  112. })
  113. },
  114. }
  115. }
  116. </script>
  117. <style lang="scss" scoped>
  118. .bb {
  119. border-bottom: 1px solid $-color-body;
  120. }
  121. .content-wrapper {
  122. height: 900rpx;
  123. .sticky {
  124. width: 100vw;
  125. }
  126. .sticky-title {
  127. padding: 24rpx 0;
  128. text-align: center;
  129. }
  130. .container {
  131. height: 712rpx;
  132. display: flex;
  133. // 左侧菜单
  134. .left-menu {
  135. width: 160rpx;
  136. .submenu {
  137. height: 90rpx;
  138. line-height: 90rpx;
  139. text-align: center;
  140. font-size: 26rpx;
  141. }
  142. // 菜单选中
  143. .active {
  144. font-weight: 500;
  145. color: $-color-primary;
  146. position: relative;
  147. background-color: rgba($-color-primary, 0.1);
  148. }
  149. .active::before {
  150. content: '';
  151. width: 6rpx;
  152. height: 30rpx;
  153. position: absolute;
  154. left: 10rpx;
  155. top: 50%;
  156. transform: translateY(-50%);
  157. background-color: $-color-primary;
  158. }
  159. }
  160. // 右侧内容
  161. .right-content {
  162. width: 100%;
  163. .tags {
  164. padding: 20rpx;
  165. .tags-item {
  166. margin-bottom: 30rpx;
  167. }
  168. image {
  169. width: 120rpx;
  170. height: 120rpx;
  171. border-radius: 50%;
  172. position: relative;
  173. }
  174. image::after {
  175. content: '';
  176. color: #FFFFFF;
  177. font-size: 50rpx;
  178. font-weight: 500;
  179. text-align: center;
  180. line-height: 120rpx;
  181. width: 120rpx;
  182. height: 120rpx;
  183. position: absolute;
  184. border-radius: 50%;
  185. left: 0;
  186. top: 0;
  187. background: rgba(0, 0, 0, 0.1) url('/bundle_b/static/icon_tags.png') no-repeat center center;
  188. background-size: 40rpx;
  189. }
  190. }
  191. }
  192. }
  193. }
  194. </style>