discover_topic.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. <template>
  2. <view :data-theme="theme">
  3. <view class="header borderPad header-box">
  4. <text class="title">话题</text>
  5. <text class="iconfont icon-guanbi5" @click="close"></text>
  6. </view>
  7. <view class='search acea-row row-between-wrapper'>
  8. <view class='input acea-row row-middle'>
  9. <text class='iconfont icon-sousuo2'></text>
  10. <input class="placeholder" type='text' :value='searchValue' :focus="focus" placeholder='点击搜索话题'
  11. placeholder-class='placeholder' @input="setValue" @confirm="searchBut" maxlength="20"></input>
  12. </view>
  13. <view class='bnt' @tap='searchBut'>搜索</view>
  14. </view>
  15. <view class="topic-recommend">
  16. <view class="topic-title acea-row row-middle"><text class="dian mr10"></text>推荐话题</view>
  17. <view class="list acea-row">
  18. <view v-for="item in topicRecommendList" :key="item.id" :class="item.isChoose ? 'active' : ''"
  19. @click="onCheck(item)" class="item borderPad mr20 mb30"><text
  20. :class="item.isChoose ? 'font-color' : ''" class="icon">#</text>{{item.name}}
  21. </view>
  22. </view>
  23. </view>
  24. <view class="topic-recommend">
  25. <view class="topic-title mt10 acea-row row-middle"><text class="dian mr10"></text>全部话题</view>
  26. <view class="list acea-row" style="border: none;">
  27. <view v-for="item in topicList" :key="item.id" @click="onCheck(item)"
  28. :class="item.isChoose ? 'active' : ''" class="item borderPad mr20 mb30">
  29. <text class="icon" :class="item.isChoose ? 'font-color' : ''">#</text>{{item.name}}
  30. </view>
  31. </view>
  32. </view>
  33. <view class="foot_bar">
  34. <button class="confirm_btn" @click="submit">确定({{topicSelectedList.length}}/5)</button>
  35. </view>
  36. </view>
  37. </template>
  38. <script>
  39. import {
  40. mapGetters
  41. } from "vuex";
  42. import {
  43. topicListApi,
  44. topicRecommendListApi,
  45. } from '@/api/discover.js';
  46. let app = getApp();
  47. export default {
  48. computed: mapGetters(['discoverTopic']),
  49. data() {
  50. return {
  51. focus: false,
  52. searchValue: '',
  53. theme: app.globalData.theme,
  54. where: {
  55. page: 1,
  56. limit: 30,
  57. keywords: '',
  58. },
  59. loaded: false,
  60. loading: false,
  61. topicList: [], //全部
  62. topicRecommendList: [], //推荐
  63. topicSelectedList: [] //选中
  64. }
  65. },
  66. mounted() {
  67. this.topicSelectedList = [...this.discoverTopic];
  68. this.getTopicList();
  69. this.getTopicRecommendList();
  70. },
  71. onReachBottom() {
  72. this.getTopicList();
  73. },
  74. methods: {
  75. close() {
  76. this.$emit('onClose');
  77. },
  78. /*获取初始化选中的数据*/
  79. getInitchecked(arr) {
  80. let that = this;
  81. arr.forEach((item, index) => {
  82. that.$set(item, 'check', false);
  83. that.topicSelectedList.forEach((val, i) => {
  84. if ((item.id == val.id)) {
  85. that.$set(item, 'isChoose', true);
  86. }
  87. })
  88. })
  89. },
  90. searchBut(){
  91. this.focus = false;
  92. this.where.page = 1;
  93. this.loaded = false;
  94. this.loading= false;
  95. this.topicList = [];
  96. this.getTopicList();
  97. },
  98. //搜索
  99. onBlur(){
  100. },
  101. setValue: function(event) {
  102. this.$set(this, 'searchValue', event.detail.value);
  103. },
  104. /*确定提交*/
  105. submit() {
  106. this.$store.commit('DiscoverTopic',this.topicSelectedList);
  107. this.$emit('onClose',this.topicSelectedList)
  108. },
  109. //点击
  110. onCheck(item) {
  111. if (this.topicSelectedList.length > 4 && !item.isChoose) {
  112. return;
  113. }
  114. let list = [...this.topicRecommendList, ...this.topicList]
  115. list.forEach((val, i) => {
  116. if ((val.id == item.id)) {
  117. this.$set(val, 'isChoose', !val.isChoose);
  118. }
  119. })
  120. if (item.isChoose) {
  121. this.topicSelectedList.push(item)
  122. } else {
  123. this.topicSelectedList.splice(this.topicSelectedList.findIndex(itemn => ((itemn.id == item.id))), 1)
  124. }
  125. },
  126. //全部
  127. getTopicList() {
  128. if (this.loading || this.loaded) return;
  129. this.loading = true;
  130. this.where.keywords = encodeURIComponent(this.searchValue);
  131. topicListApi(this.where).then(
  132. res => {
  133. this.loadingb = false;
  134. this.loaded = res.data.list.length < this.where.limit;
  135. this.topicList.push.apply(this.topicList, res.data.list);
  136. this.where.page = this.where.page + 1;
  137. this.topicList.forEach((item, index) => {
  138. this.$set(item, 'isChoose', false);
  139. })
  140. this.getInitchecked(this.topicList);
  141. },
  142. error => {
  143. this.$util.Tips({
  144. title: error.message
  145. })
  146. }
  147. );
  148. },
  149. //推荐
  150. getTopicRecommendList() {
  151. topicRecommendListApi().then(
  152. res => {
  153. this.topicRecommendList = res.data;
  154. this.topicRecommendList.forEach((item, index) => {
  155. this.$set(item, 'isChoose', false);
  156. })
  157. this.getInitchecked(this.topicRecommendList);
  158. },
  159. error => {
  160. this.$util.Tips({
  161. title: error.message
  162. })
  163. }
  164. );
  165. }
  166. }
  167. }
  168. </script>
  169. <style lang="scss" scoped>
  170. .header {
  171. position: relative;
  172. text-align: center;
  173. margin-bottom: 30rpx;
  174. margin-top: 30rpx;
  175. .title {
  176. color: #282828;
  177. font-size: 36rpx;
  178. font-weight: bold;
  179. }
  180. .iconfont {
  181. color: #8A8A8A;
  182. font-size: 28rpx;
  183. position: absolute;
  184. top: 4rpx;
  185. right: 24rpx;
  186. }
  187. }
  188. .foot_bar {
  189. width: 100%;
  190. position: fixed;
  191. bottom: 0;
  192. left: 0;
  193. background: #ffffff;
  194. padding: 20rpx 0;
  195. z-index: 5;
  196. .confirm_btn {
  197. width: 710rpx;
  198. height: 86rpx;
  199. line-height: 84rpx;
  200. color: #ffffff;
  201. text-align: center;
  202. font-size: 32rpx;
  203. @include main_bg_color(theme);
  204. border-radius: 43rpx;
  205. margin: 0 auto;
  206. }
  207. }
  208. .topic {
  209. &-recommend {
  210. padding: 30rpx 0 0 30rpx;
  211. .dian {
  212. width: 10rpx;
  213. height: 10rpx;
  214. border-radius: 50%;
  215. opacity: 1;
  216. @include main_bg_color(theme);
  217. }
  218. .list {
  219. border-bottom: 1px solid #EEEEEE;
  220. padding-bottom: 20rpx;
  221. .active {
  222. @include cate-two-btn(theme);
  223. @include main_color(theme);
  224. border: none;
  225. }
  226. }
  227. .item {
  228. height: 62rpx;
  229. line-height: 59rpx;
  230. border-radius: 31rpx;
  231. border: 1px solid #CCCCCC;
  232. color: #282828;
  233. font-size: 24rpx;
  234. .icon {
  235. color: #999999;
  236. margin-right: 6rpx;
  237. }
  238. }
  239. .item:nth-last-child(1) {
  240. margin-right: 0;
  241. }
  242. }
  243. &-title {
  244. font-weight: 600;
  245. color: #282828;
  246. font-size: 30rpx;
  247. margin-bottom: 30rpx;
  248. }
  249. }
  250. .search {
  251. padding: 0 24rpx 18rpx 30rpx;
  252. background-color: #fff !important;
  253. .input {
  254. width: 610rpx;
  255. background-color: #f7f7f7;
  256. border-radius: 33rpx;
  257. padding: 0 35rpx;
  258. box-sizing: border-box;
  259. height: 66rpx;
  260. input {
  261. width: 472rpx;
  262. font-size: 26rpx;
  263. }
  264. .placeholder {
  265. color: #bbb;
  266. }
  267. .iconfont {
  268. color: #000;
  269. font-size: 35rpx;
  270. }
  271. }
  272. .bnt {
  273. text-align: center;
  274. height: 66rpx;
  275. line-height: 66rpx;
  276. font-size: 30rpx;
  277. color: #282828;
  278. }
  279. }
  280. .header-box{
  281. height: 50rpx;
  282. line-height: 50rpx;
  283. }
  284. .placeholder{
  285. margin-left: 16rpx;
  286. }
  287. </style>