news.nvue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <template>
  2. <gracePage headerBG="#FFFFFF" flexVal="1">
  3. <view slot="gHeader" class="grace-body" style="padding-top:6px;">
  4. <graceNavBar :items="tabs" :currentIndex="currentIndex" @change="navChange"></graceNavBar>
  5. </view>
  6. <view slot="gBody" class="grace-flex-v1" ref="gBody">
  7. <swiper :style="{height:mainHeight+'px'}" :current="currentIndex" @change="swiperChange">
  8. <swiper-item v-for="(news, newsIndex) in newsAll" :key="newsIndex">
  9. <scroll-view scroll-y="true" :style="{height:mainHeight+'px'}"
  10. @scrolltolower="scrollend" @scroll="scroll"
  11. @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend">
  12. <graceReload ref="graceReload" @reload="reload" width="700rpx" marginLeft="25rpx"></graceReload>
  13. <graceEmpty v-if="news == 'empty'">
  14. <view slot="img" class="empty-view">
  15. <!-- 请根据您的项目要求制作并更换为空图片 -->
  16. <image class="empty-img" mode="widthFix" src="https://staticimgs.oss-cn-beijing.aliyuncs.com/empty.png"></image>
  17. </view>
  18. <text slot="text" class="grace-text-small grace-gray">本栏目暂无新闻</text>
  19. </graceEmpty>
  20. <view class="grace-body">
  21. <view v-for="(item, index) in news" :key="index" v-if="news != 'empty'" >
  22. <view class="grace-news-list grace-border-b" v-if="item.imgs.length < 3" @tap="newsinfo">
  23. <view class="grace-news-item">
  24. <view class="grace-news-img grace-news-img-l">
  25. <image :src="item.imgs[0]" mode="widthFix" class="grace-news-img-in"></image>
  26. </view>
  27. <view class="grace-news-body">
  28. <text class="grace-news-title">{{item.title}}</text>
  29. <text class="grace-news-desc">{{item.desc}}</text>
  30. </view>
  31. </view>
  32. <view class="grace-news-info">
  33. <view style="width:500rpx;" class="grace-nowrap">
  34. <text class="grace-icons grace-news-info-text">&#xe609; {{item.viewnum}}</text>
  35. <text class="grace-icons grace-news-info-text" style="margin-left:30rpx;">&#xe69e; {{item.author}} · {{item.catename}}</text>
  36. </view>
  37. <text class="grace-icons grace-news-info-text">&#xe6b8; 208</text>
  38. </view>
  39. </view>
  40. <view class="grace-news-list grace-border-b" v-if="item.imgs.length >= 3" @tap="newsinfo">
  41. <text class="grace-news-title">{{item.title}}</text>
  42. <view class="grace-news-img-list">
  43. <view class="grace-news-imgs" v-for="(img, imgIndex) in item.imgs" :key="imgIndex">
  44. <image :src="img" mode="widthFix" class="grace-news-imgs-img"></image>
  45. </view>
  46. </view>
  47. <view class="grace-news-info">
  48. <view style="width:500rpx;" class="grace-nowrap">
  49. <text class="grace-icons grace-news-info-text">&#xe609; {{item.viewnum}}</text>
  50. <text class="grace-icons grace-news-info-text" style="margin-left:30rpx;">&#xe69e; {{item.author}} · {{item.catename}}</text>
  51. </view>
  52. <text class="grace-icons grace-news-info-text">&#xe6b8; 2081</text>
  53. </view>
  54. </view>
  55. </view>
  56. </view>
  57. <graceLoading :loadingType="loadingTypes[newsIndex]"></graceLoading>
  58. </scroll-view>
  59. </swiper-item>
  60. </swiper>
  61. </view>
  62. </gracePage>
  63. </template>
  64. <script>
  65. import gracePage from "../../graceUI/weexComponents/gracePage.nvue";
  66. import graceNavBar from "../../graceUI/weexComponents/graceNavBar.nvue";
  67. import graceLoading from "../../graceUI/weexComponents/graceLoading.nvue";
  68. import graceEmpty from '../../graceUI/weexComponents/graceEmptyNew.nvue';
  69. import graceReload from '../../graceUI/weexComponents/graceReload.nvue';
  70. const dom = weex.requireModule('dom');
  71. export default {
  72. data() {
  73. return {
  74. currentIndex: 0,
  75. mainHeight : 500,
  76. //分类数据
  77. tabsAll : [],
  78. tabs : [],
  79. // 新闻信息保存数组
  80. newsAll : [],
  81. // 每个选项卡对应的分页
  82. pages : [],
  83. // 加载状态
  84. loadingTypes : [],
  85. // 每个滚动区域的滚动值
  86. scrollTops : []
  87. }
  88. },
  89. onReady:function(){
  90. setTimeout(()=>{
  91. // 获取顶部内容高度
  92. var el = this.$refs.gBody;
  93. dom.getComponentRect(el, (res) => {
  94. this.mainHeight = res.size.height;
  95. });
  96. },1000);
  97. //加载分类信息 初始化数据
  98. this.getCate();
  99. },
  100. watch:{
  101. currentIndex : function (nVal, oldVal) {
  102. if( this.loadingTypes[this.currentIndex] != 2 || this.loadingTypes[this.currentIndex] != 4){ this.getNews(); }
  103. }
  104. },
  105. methods:{
  106. navChange: function (e) {
  107. this.currentIndex = e;
  108. },
  109. swiperChange: function (e) {
  110. var index = e.detail.current;
  111. this.currentIndex = index;
  112. },
  113. //加载分类信息 初始化数据
  114. getCate : function () {
  115. uni.request({
  116. // 此处可以获取分类 根据分类自己拼接请求地址
  117. // 格式请参考 接口 [ 浏览器运行直接查看 ]
  118. url : 'http://grace.hcoder.net/api/tabs',
  119. method : 'GET',
  120. data : {},
  121. success : res => {
  122. // 初始化新闻列表数组 元素数量与分类匹配
  123. this.tabsAll = res.data.data;
  124. for(var i = 0; i < this.tabsAll.length; i++){
  125. this.newsAll.push([]);
  126. this.tabs.push(this.tabsAll[i].txt);
  127. this.pages.push(1);
  128. this.loadingTypes.push(3);
  129. this.scrollTops.push(0);
  130. }
  131. this.getNews();
  132. }
  133. });
  134. },
  135. // 加载新闻
  136. getNews : function(isReload){
  137. // 当前正在展示的 选项index 为 this.currentIndex
  138. // 那么分类 id 应该为 this.tabsAll[this.currentIndex].id
  139. //console.log('类型 : ' + this.tabs[this.currentIndex] + ' 第'+ this.pages[this.currentIndex] +'页');
  140. if(!isReload){this.loadingTypes.splice(this.currentIndex, 1, 1);}
  141. //console.log('http://grace.hcoder.net/api/news/index/'+this.tabsAll[this.currentIndex].id+'/'+this.pages[this.currentIndex]);
  142. uni.request({
  143. // 此处可以获取分类 根据分类自己拼接请求地址
  144. // 分类 id 、页码 都已经获取到了
  145. url : 'http://grace.hcoder.net/api/news/index/'+this.tabsAll[this.currentIndex].id+'/'+this.pages[this.currentIndex],
  146. method : 'GET',
  147. data : {},
  148. success : res => {
  149. if(res.data.status == 'ok'){
  150. // 第一页
  151. if(this.pages[this.currentIndex] == 1){
  152. this.newsAll.splice(this.currentIndex, 1 , res.data.data);
  153. }
  154. // 之后的加载页
  155. else{
  156. this.newsAll[this.currentIndex] = this.newsAll[this.currentIndex].concat(res.data.data);
  157. }
  158. // 页码增加
  159. this.pages[this.currentIndex]++;
  160. setTimeout(()=>{
  161. this.loadingTypes.splice(this.currentIndex, 1, 3);
  162. },300)
  163. }else if(res.data.status == 'empty'){
  164. console.log('empty');
  165. this.newsAll[this.currentIndex] = 'empty';
  166. this.loadingTypes.splice(this.currentIndex, 1, 4);
  167. }else if(res.data.status == 'nomore'){
  168. console.log('nomore');
  169. this.loadingTypes.splice(this.currentIndex, 1, 2);
  170. }
  171. },
  172. complete: () => {
  173. if(isReload){
  174. setTimeout(()=>{
  175. this.$refs.graceReload[this.currentIndex].endReload();
  176. },300)
  177. }
  178. }
  179. });
  180. },
  181. // 点击新闻列表
  182. newsinfo : function () {
  183. uni.navigateTo({
  184. url:'../artInfo/artInfo'
  185. })
  186. },
  187. // 加载更多
  188. scrollend:function(e){
  189. // 判断加载状态避免多次滚动时有加载尚未完成
  190. if( this.loadingTypes[this.currentIndex] == 2 || this.loadingTypes[this.currentIndex] == 4){ return false; }
  191. console.log('loadmore.....');
  192. this.getNews();
  193. },
  194. scroll:function(e){
  195. this.scrollTops[this.currentIndex] = e.detail.scrollTop;
  196. },
  197. touchstart : function (e){
  198. var touchObj = {scrollTop : this.scrollTops[this.currentIndex], moveY : e.changedTouches[0].pageY};
  199. this.$refs.graceReload[this.currentIndex].touchstart(touchObj);
  200. },
  201. touchmove : function (e) {
  202. var touchObj = {scrollTop : this.scrollTops[this.currentIndex], moveY : e.changedTouches[0].pageY};
  203. this.$refs.graceReload[this.currentIndex].touchmove(touchObj);
  204. },
  205. touchend : function (e) {
  206. var touchObj = {scrollTop : this.scrollTops[this.currentIndex], moveY : e.changedTouches[0].pageY};
  207. this.$refs.graceReload[this.currentIndex].touchend(touchObj);
  208. },
  209. // 下拉刷新
  210. reload:function(){
  211. this.pages[this.currentIndex] = 1;
  212. this.loadingTypes.splice(this.currentIndex, 1, 3);
  213. this.getNews(1);
  214. }
  215. },
  216. components:{gracePage, graceNavBar, graceEmpty, graceLoading, graceReload}
  217. }
  218. </script>
  219. <style>
  220. .grace-news-img{width:220rpx; height:150rpx; overflow:hidden; font-size:0;}
  221. .grace-news-imgs-img{width:225rpx; height:380rpx;}
  222. .empty-view{width:280rpx; height:280rpx; border-radius:280rpx; background-color:#F6F7F8; margin-top:300rpx;}
  223. .empty-img{width:220rpx; height:200rpx; margin:40rpx; border-radius:200rpx;}
  224. .grace-text-small{margin-top:10px;}
  225. .grace-news-body{align-self:flex-start;}
  226. </style>