index.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. <template>
  2. <view class="main">
  3. <view class="one">
  4. <tabs :tabs="tabs" @tabsChange="tabsChange">
  5. <view class="tabsList">
  6. <scroll-view scroll-y="true" class="scroll-view" @scrolltolower="toPage" @scroll="toScroll">
  7. <view class="list-scroll-view">
  8. <!-- 瀑布流布局列表 -->
  9. <view class="pubuBox">
  10. <view class="pubuItem">
  11. <view class="list" v-for="(item, index) in list" :key="index" @tap="toInfo(item)">
  12. <image v-if="item.file.length>0" :src="item.file&&item.file.length>0?item.file[0].url:''" mode="widthFix">
  13. </image>
  14. <image v-else :src="config.file&&config.file.length>0?config.file[0].url:''" mode="widthFix">
  15. </image>
  16. <view class="title"> <!-- 这是没有高度的父盒子(下半部分) -->
  17. <view class="title_1">{{ item.title ||item.name||'暂无'}}</view>
  18. <view class="title_2">
  19. <view class="left textOver">
  20. {{item.contact_name||item.address||'暂无'}}
  21. </view>
  22. <view class="right" @tap.stop="toLike(item)">
  23. <text class="iconfont icon-shoucang"></text>
  24. {{item.collect_num||'0'}}
  25. </view>
  26. </view>
  27. </view>
  28. </view>
  29. </view>
  30. </view>
  31. <view class="is_bottom" v-if="is_bottom">
  32. <text>{{config.bottom_title||'到底了!'}}</text>
  33. </view>
  34. </view>
  35. </scroll-view>
  36. </view>
  37. </tabs>
  38. </view>
  39. </view>
  40. </template>
  41. <script>
  42. import tabs from '../../components/tabs/index.vue';
  43. export default {
  44. components: {
  45. tabs
  46. },
  47. data() {
  48. return {
  49. config: {},
  50. user: {},
  51. tabs: {
  52. active: 'article',
  53. bgColor: '#ffffff',
  54. menu: [{
  55. title: '游玩攻略',
  56. active: 'article'
  57. },
  58. {
  59. title: '酒店民宿',
  60. active: 'hotel'
  61. },
  62. {
  63. title: '美食特色',
  64. active: 'location'
  65. },
  66. {
  67. title: '景区门票',
  68. active: 'ticket'
  69. }
  70. ]
  71. },
  72. list: [],
  73. total: 0,
  74. skip: 0,
  75. limit: 6,
  76. page: 0,
  77. // 数据是否触底
  78. is_bottom: false,
  79. scrollTop: 0,
  80. }
  81. },
  82. onLoad: async function(e) {
  83. const that = this;
  84. that.searchToken();
  85. that.searchConfig();
  86. },
  87. onShow: async function() {
  88. const that = this;
  89. that.clearPage();
  90. await that.search();
  91. },
  92. onPullDownRefresh: async function() {
  93. const that = this;
  94. that.clearPage();
  95. await that.search();
  96. uni.stopPullDownRefresh();
  97. },
  98. methods: {
  99. searchToken() {
  100. const that = this;
  101. try {
  102. const res = uni.getStorageSync('token');
  103. if (res) that.$set(that, `user`, res);
  104. } catch (e) {
  105. uni.showToast({
  106. title: err.errmsg,
  107. icon: 'error',
  108. duration: 2000
  109. });
  110. }
  111. },
  112. searchConfig() {
  113. const that = this;
  114. try {
  115. const res = uni.getStorageSync('config');
  116. if (res) that.$set(that, `config`, res);
  117. } catch (e) {
  118. uni.showToast({
  119. title: err.errmsg,
  120. icon: 'error',
  121. duration: 2000
  122. });
  123. }
  124. },
  125. async search() {
  126. const that = this;
  127. if (!that.user._id) return
  128. let info = {
  129. skip: that.skip,
  130. limit: that.limit,
  131. user: that.user._id,
  132. source_type: that.tabs.active,
  133. type: '1'
  134. }
  135. const res = await that.$api(`/like/article`, 'GET', {
  136. ...info,
  137. ...that.searchInfo
  138. })
  139. if (res.errcode == '0') {
  140. let list = [...that.list, ...res.data];
  141. that.$set(that, `list`, list)
  142. that.$set(that, `total`, res.total)
  143. } else {
  144. uni.showToast({
  145. title: res.errmsg,
  146. });
  147. }
  148. },
  149. // 选择选项卡
  150. tabsChange(e) {
  151. const that = this;
  152. that.$set(that.tabs, `active`, e.active)
  153. that.clearPage();
  154. that.search()
  155. },
  156. // 查看详情
  157. toInfo(item) {
  158. const that = this;
  159. if (that.tabs.active == 'article') {
  160. uni.navigateTo({
  161. url: `/pagesHome/article/index?id=${item.id||item._id}`
  162. })
  163. } else if (that.tabs.active == 'hotel') {
  164. uni.navigateTo({
  165. url: `/pagesHome/hotel/info?id=${item.id||item._id}`
  166. })
  167. } else if (that.tabs.active == 'location') {
  168. uni.navigateTo({
  169. url: `/pagesHome/type/info?id=${item.id||item._id}`
  170. })
  171. } else if (that.tabs.active == 'ticket') {
  172. uni.navigateTo({
  173. url: `/pagesHome/ticket/info?id=${item.id||item._id}`
  174. })
  175. }
  176. },
  177. // 取消收藏
  178. async toLike(item) {
  179. const that = this;
  180. let res;
  181. res = await that.$api(`/like/${item.collect}`, 'DELETE', {})
  182. if (res.errcode == '0') {
  183. that.clearPage();
  184. that.search()
  185. }
  186. },
  187. // 分页
  188. toPage(e) {
  189. const that = this;
  190. let list = that.list;
  191. let limit = that.limit;
  192. if (that.total > list.length) {
  193. uni.showLoading({
  194. title: '加载中',
  195. mask: true
  196. })
  197. let page = that.page + 1;
  198. that.$set(that, `page`, page)
  199. let skip = page * limit;
  200. that.$set(that, `skip`, skip)
  201. that.search();
  202. uni.hideLoading();
  203. } else that.$set(that, `is_bottom`, true)
  204. },
  205. toScroll(e) {
  206. const that = this;
  207. let up = that.scrollTop;
  208. that.$set(that, `scrollTop`, e.detail.scrollTop);
  209. let num = Math.sign(up - e.detail.scrollTop);
  210. if (num == 1) that.$set(that, `is_bottom`, false);
  211. },
  212. // 清空列表
  213. clearPage() {
  214. const that = this;
  215. that.$set(that, `list`, [])
  216. that.$set(that, `skip`, 0)
  217. that.$set(that, `limit`, 6)
  218. that.$set(that, `page`, 0)
  219. }
  220. }
  221. }
  222. </script>
  223. <style lang="scss" scoped>
  224. .main {
  225. display: flex;
  226. flex-direction: column;
  227. width: 100vw;
  228. height: 100vh;
  229. .one {
  230. position: relative;
  231. flex-grow: 1;
  232. background-color: var(--f9Color);
  233. margin: 2vw 0 0 0;
  234. .tabsList {
  235. position: relative;
  236. width: 100vw;
  237. height: 90vh;
  238. .pubuBox {
  239. padding: 2vw;
  240. }
  241. .pubuItem {
  242. column-count: 2;
  243. column-gap: 2vw;
  244. }
  245. .list {
  246. box-sizing: border-box;
  247. border-radius: 2vw;
  248. overflow: hidden;
  249. background-color: var(--mainColor);
  250. break-inside: avoid;
  251. /*避免在元素内部插入分页符*/
  252. box-sizing: border-box;
  253. margin-bottom: 2vw;
  254. }
  255. .list image {
  256. width: 100%;
  257. }
  258. .title {
  259. padding: 2vw;
  260. .title_1 {
  261. font-size: var(--font14Size);
  262. line-height: 4.5vw;
  263. text-overflow: -o-ellipsis-lastline;
  264. overflow: hidden;
  265. text-overflow: ellipsis;
  266. display: -webkit-box;
  267. -webkit-line-clamp: 2;
  268. line-clamp: 2;
  269. -webkit-box-orient: vertical;
  270. min-height: 6vw;
  271. max-height: 20vw;
  272. }
  273. .title_2 {
  274. display: flex;
  275. justify-content: space-between;
  276. font-size: var(--font12Size);
  277. color: var(--f69Color);
  278. padding: 1vw 0;
  279. .right {
  280. display: flex;
  281. align-items: center;
  282. text:first-child {
  283. padding: 0 1vw 0 0;
  284. }
  285. }
  286. }
  287. }
  288. }
  289. }
  290. }
  291. .scroll-view {
  292. position: absolute;
  293. top: 0;
  294. left: 0;
  295. right: 0;
  296. bottom: 0;
  297. .list-scroll-view {
  298. display: flex;
  299. flex-direction: column;
  300. }
  301. }
  302. .is_bottom {
  303. width: 100%;
  304. text-align: center;
  305. text {
  306. padding: 2vw 0;
  307. display: inline-block;
  308. color: var(--f85Color);
  309. font-size: var(--font14Size);
  310. }
  311. }
  312. </style>