index.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. <template>
  2. <view :data-theme="theme">
  3. <tui-skeleton v-if="showSkeleton"></tui-skeleton>
  4. <view class='newsList tui-skeleton' :style="{visibility: showSkeleton ? 'hidden' : 'visible'}">
  5. <view class='swiper tui-skeleton-rect' v-if="imgUrls.length > 0">
  6. <swiper indicator-dots="true" :autoplay="autoplay" :circular="circular" :interval="interval" :duration="duration"
  7. indicator-color="rgba(102,102,102,0.3)" indicator-active-color="#666">
  8. <block v-for="(item,index) in imgUrls" :key="index">
  9. <swiper-item>
  10. <navigator :url="'/pages/news_details/index?id='+item.id">
  11. <image :src="item.cover" class="slide-image" mode="aspectFill" />
  12. </navigator>
  13. </swiper-item>
  14. </block>
  15. </swiper>
  16. </view>
  17. <view class='nav'>
  18. <scroll-view class="scroll-view_x" scroll-x scroll-with-animation :scroll-left="scrollLeft" style="width:auto;overflow:hidden;">
  19. <block v-for="(item,index) in navList" :key="index">
  20. <view class='item borRadius14 tui-skeleton-rect' :class='active==item.id?"on":""' @click='tabSelect(item.id, index)'>
  21. <view class="line1">{{item.name}}</view>
  22. <view class='line bg_color' v-if="active==item.id"></view>
  23. </view>
  24. </block>
  25. </scroll-view>
  26. </view>
  27. <view class='list'>
  28. <block v-for="(item,index) in articleList" :key="index">
  29. <view class='item acea-row row-between-wrapper' @click="toNewDetail(item.id)">
  30. <view class='text acea-row row-column-between'>
  31. <view class='name line2 tui-skeleton-rect'>{{item.title}}</view>
  32. <view class="tui-skeleton-rect">{{item.createTime}}</view>
  33. </view>
  34. <view class='pictrue tui-skeleton-rect'>
  35. <image :src='item.cover'></image>
  36. </view>
  37. </view>
  38. </block>
  39. </view>
  40. <view class='loadingicon acea-row row-center-wrapper'>
  41. <text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>
  42. </view>
  43. </view>
  44. <view class='noCommodity' v-if="articleList.length == 0 && (page != 1 || active== 0) && isShow">
  45. <view class='pictrue'>
  46. <image :src="urlDomain+'crmebimage/presets/noguanzhu.png'"></image>
  47. </view>
  48. </view>
  49. </view>
  50. </template>
  51. <script>
  52. // +----------------------------------------------------------------------
  53. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  54. // +----------------------------------------------------------------------
  55. // | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
  56. // +----------------------------------------------------------------------
  57. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  58. // +----------------------------------------------------------------------
  59. // | Author: CRMEB Team <admin@crmeb.com>
  60. // +----------------------------------------------------------------------
  61. import {
  62. getArticleCategoryList,
  63. getArticleList,
  64. getArticleHotList,
  65. getArticleBannerList,
  66. } from '@/api/api.js';
  67. import animationType from '@/utils/animationType.js'
  68. import tuiSkeleton from '@/components/base/tui-skeleton.vue';
  69. let app = getApp();
  70. export default {
  71. components: {
  72. tuiSkeleton
  73. },
  74. data() {
  75. return {
  76. urlDomain: this.$Cache.get("imgHost"),
  77. showSkeleton: true, //骨架屏显示隐藏
  78. isNodes: 0, //控制什么时候开始抓取元素节点,只要数值改变就重新抓取
  79. imgUrls: [{imageInput:''}],
  80. articleList: [{imageInput:'',title: '占位占位',createTime:'占位'}],
  81. indicatorDots: false,
  82. circular: true,
  83. autoplay: true,
  84. interval: 3000,
  85. duration: 500,
  86. navList: [{id:0,name:'占位'},{id:0,name:'占位'},{id:0,name:'占位'}],
  87. active: 0,
  88. page: 1,
  89. limit: 8,
  90. status: false,
  91. scrollLeft: 0,
  92. isShow: false,
  93. theme:app.globalData.theme,
  94. loading: false
  95. };
  96. },
  97. onLoad(){
  98. setTimeout(() => {
  99. this.isNodes++;
  100. // #ifdef H5
  101. this.setShare();
  102. // #endif
  103. }, 500);
  104. this.articleList = [];
  105. this.getArticleHot();
  106. this.getArticleBanner();
  107. this.getArticleCate();
  108. this.status = false;
  109. this.page = 1;
  110. this.getCidArticle();
  111. },
  112. /**
  113. * 生命周期函数--监听页面显示
  114. */
  115. onShow: function() {
  116. },
  117. /**
  118. * 页面上拉触底事件的处理函数
  119. */
  120. onReachBottom: function () {
  121. this.getCidArticle();
  122. },
  123. methods: {
  124. getArticleHot: function() {
  125. let that = this;
  126. that.loading = true;
  127. getArticleHotList().then(res => {
  128. that.$set(that, 'articleList', res.data);
  129. that.loading = false;
  130. });
  131. },
  132. getArticleBanner: function() {
  133. let that = this;
  134. getArticleBannerList().then(res => {
  135. that.imgUrls = res.data;
  136. setTimeout(() => {
  137. this.showSkeleton = false
  138. }, 1000)
  139. });
  140. },
  141. getCidArticle: function() {
  142. let that = this;
  143. if (that.active == 0) return;
  144. let limit = that.limit;
  145. let page = that.page;
  146. let articleList = that.articleList;
  147. if (that.status) return;
  148. that.loading = true;
  149. getArticleList(that.active, {
  150. page: page,
  151. limit: limit
  152. }).then(res => {
  153. let articleListNew = [];
  154. let len = res.data.list.length;
  155. articleListNew = articleList.concat(res.data.list);
  156. that.page++;
  157. that.$set(that, 'articleList', articleListNew);
  158. that.status = limit > len;
  159. that.page = that.page;
  160. that.isShow = true;
  161. that.loading = false;
  162. });
  163. },
  164. getArticleCate: function() {
  165. let that = this;
  166. getArticleCategoryList().then(res => {
  167. let list = res.data;
  168. list.unshift({id:0,name:'热门'});
  169. that.$set(that, 'navList', list);
  170. setTimeout(() => {
  171. this.showSkeleton = false
  172. }, 1000)
  173. });
  174. },
  175. tabSelect(active,e) {
  176. this.active = active;
  177. this.scrollLeft = e * 60;
  178. if (this.active == 0) this.getArticleHot();
  179. else {
  180. this.$set(this, 'articleList', []);
  181. this.page = 1;
  182. this.status = false;
  183. this.getCidArticle();
  184. }
  185. },
  186. toNewDetail(id){
  187. uni.navigateTo({
  188. animationType: animationType.type,
  189. animationDuration: animationType.duration,
  190. url:"/pages/goods/news_details/index?id="+id
  191. })
  192. },
  193. setShare: function() {
  194. this.$wechat.isWeixin() &&
  195. this.$wechat.wechatEvevt([
  196. "updateAppMessageShareData",
  197. "updateTimelineShareData",
  198. "onMenuShareAppMessage",
  199. "onMenuShareTimeline"
  200. ], {
  201. desc: this.articleList[0].title,
  202. title: this.articleList[0].title,
  203. link: location.href,
  204. imgUrl:this.articleList[0].imageInput
  205. }).then(res => {
  206. }).catch(err => {
  207. console.log(err);
  208. });
  209. },
  210. }
  211. }
  212. </script>
  213. <style lang="scss">
  214. page {
  215. background-color: #fff !important;
  216. }
  217. .newsList .swiper {
  218. width: 100%;
  219. position: relative;
  220. box-sizing: border-box;
  221. padding: 0 30rpx;
  222. }
  223. .newsList .swiper swiper {
  224. width: 100%;
  225. height: 365rpx;
  226. position: relative;
  227. }
  228. .newsList .swiper .slide-image {
  229. width: 100%;
  230. height: 335rpx;
  231. border-radius: 14rpx;
  232. }
  233. // #ifdef MP-WEIXIN
  234. .newsList .swiper .wx-swiper-dot {
  235. width: 12rpx !important;
  236. height: 12rpx !important;
  237. border-radius: 0;
  238. transform: rotate(-45deg);
  239. transform-origin: 0 100%;
  240. }
  241. .newsList .swiper .wx-swiper-dot~.wx-swiper-dot {
  242. margin-left: 5rpx;
  243. }
  244. .newsList .swiper .wx-swiper-dots.wx-swiper-dots-horizontal {
  245. margin-bottom: -15rpx;
  246. }
  247. // #endif
  248. // #ifdef APP-PLUS || H5
  249. .newsList .swiper .uni-swiper-dot {
  250. width: 12rpx !important;
  251. height: 12rpx !important;
  252. border-radius: 0;
  253. transform: rotate(-45deg);
  254. transform-origin: 0 100%;
  255. }
  256. .newsList .swiper .uni-swiper-dot~.uni-swiper-dot {
  257. margin-left: 5rpx;
  258. }
  259. .newsList .swiper .uni-swiper-dots.uni-swiper-dots-horizontal {
  260. margin-bottom: -15rpx;
  261. }
  262. // #endif
  263. .newsList .nav {
  264. padding: 0 24rpx;
  265. width: 100%;
  266. white-space: nowrap;
  267. box-sizing: border-box;
  268. margin-top: 43rpx;
  269. }
  270. .newsList .nav .item {
  271. max-width: 156rpx;
  272. display: inline-block;
  273. font-size: 32rpx;
  274. color: #999;
  275. }
  276. .newsList .nav .item.on {
  277. color: #282828;
  278. }
  279. .newsList .nav .item~.item {
  280. margin-left: 46rpx;
  281. }
  282. .newsList .nav .item .line {
  283. width: 24rpx;
  284. height: 4rpx;
  285. border-radius: 2rpx;
  286. margin: 10rpx auto 0 auto;
  287. @include main_bg_color(theme);
  288. }
  289. .newsList .list .item {
  290. margin: 0 24rpx;
  291. border-bottom: 1rpx solid #f0f0f0;
  292. padding: 35rpx 0;
  293. }
  294. .newsList .list .item .pictrue {
  295. width: 250rpx;
  296. height: 156rpx;
  297. }
  298. .newsList .list .item .pictrue image {
  299. width: 100%;
  300. height: 100%;
  301. border-radius: 14rpx;
  302. }
  303. .newsList .list .item .text {
  304. width: 420rpx;
  305. height: 156rpx;
  306. font-size: 24rpx;
  307. color: #999;
  308. }
  309. .newsList .list .item .text .name {
  310. font-size: 30rpx;
  311. color: #282828;
  312. }
  313. .newsList .list .item .picList .pictrue {
  314. width: 335rpx;
  315. height: 210rpx;
  316. margin-top: 30rpx;
  317. }
  318. .newsList .list .item .picList.on .pictrue {
  319. width: 217rpx;
  320. height: 136rpx;
  321. }
  322. .newsList .list .item .picList .pictrue image {
  323. width: 100%;
  324. height: 100%;
  325. border-radius: 6rpx;
  326. }
  327. .newsList .list .item .time {
  328. text-align: right;
  329. font-size: 24rpx;
  330. color: #999;
  331. margin-top: 22rpx;
  332. }
  333. </style>