news-list.vue 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. <!-- 在这个文件对每个tab对应的列表进行渲染 -->
  2. <template>
  3. <view class="content">
  4. <!-- 这里设置了z-paging加载时禁止自动调用reload方法,自行控制何时reload(懒加载)-->
  5. <z-paging ref="paging" v-model="dataList" @query="queryList" use-page-scroll :hide-empty-view="hideEmptyView"
  6. :refresher-enabled="false" @contentHeightChanged="contentHeightChanged" :auto="false">
  7. <!-- 如果希望其他view跟着页面滚动,可以放在z-paging标签内 -->
  8. <view class="item" v-for="(item, index) in dataList" :key="index" @click="toDetail(item.id)">
  9. <view class="itemTitle">
  10. {{ formatTitle(item.title) }}
  11. <text v-if="item.title.length > 90" class="allContent">全文</text>
  12. </view>
  13. <view class="resources" v-if="item.clueInfoList.length <= 1">
  14. <view class="resourcesItem resourcesItemOne" v-for="items in item.clueInfoList" :key="items.id">
  15. <image v-if="items.type == '1'" mode="aspectFill" class="logo" :src="items.localUrl"></image>
  16. <image v-if="items.type == '2'" class="logo" src="../../static/image/video.png"></image>
  17. <image v-if="items.type == '3'" class="logo" src="../../static/image/music.png"></image>
  18. <image v-if="items.type == 2 || items.type == 3" src="../../static/image/playBtn.png"
  19. class="playBtn"></image>
  20. </view>
  21. </view>
  22. <view class="resources" v-else>
  23. <view class="resourcesItem resourcesItems" v-for="items in item.clueInfoList" :key="items.id">
  24. <image v-if="items.type == '1'" class="logo" mode="aspectFill" :src="items.localUrl"></image>
  25. <image v-if="items.type == '2'" class="logo" src="../../static/image/video.png"></image>
  26. <image v-if="items.type == '3'" class="logo" src="../../static/image/music.png"></image>
  27. <image v-if="items.type == 2 || items.type == 3" src="../../static/image/playBtn.png"
  28. class="playBtn"></image>
  29. </view>
  30. <view class="resourcesItem resourcesItems" v-if="item.clueInfoList.length % 3 == 2"></view>
  31. </view>
  32. <view class="bottomBox">
  33. <view class="momentBox">
  34. <view class="author" v-if="tabIndex == 3">{{ formatName(item.author) }}</view>
  35. <image src="../../static/image/moment.png" class="momentImg"></image>
  36. <text>{{ item.replyCount }}</text>
  37. </view>
  38. <view class="timeBox">{{ item.modifyTime }}</view>
  39. </view>
  40. <view class="seat"></view>
  41. </view>
  42. </z-paging>
  43. </view>
  44. </template>
  45. <script>
  46. import {
  47. findPage
  48. } from '../../network/api.js';
  49. export default {
  50. data() {
  51. return {
  52. //v-model绑定的这个变量不要在分页请求结束中自己赋值!!!
  53. dataList: [],
  54. height: 0,
  55. hideEmptyView: true,
  56. completeFunc: null
  57. };
  58. },
  59. props: {
  60. //当前组件的index,也就是当前组件是swiper中的第几个
  61. tabIndex: {
  62. type: Number,
  63. default: function() {
  64. return 0;
  65. }
  66. },
  67. //当前swiper切换到第几个index
  68. currentIndex: {
  69. type: Number,
  70. default: function() {
  71. return 0;
  72. }
  73. },
  74. title: {
  75. type: String,
  76. default: function() {
  77. return '';
  78. }
  79. }
  80. },
  81. watch: {
  82. currentIndex: {
  83. handler(newVal) {
  84. if (newVal === this.tabIndex) {
  85. //懒加载,当滑动到当前的item时,才去加载
  86. setTimeout(() => {
  87. this.$refs.paging.reload();
  88. }, 100);
  89. }
  90. },
  91. immediate: true
  92. }
  93. },
  94. methods: {
  95. formatName(name, index = 7) {
  96. return name.length > index ? name.substring(0, index - 1) + '...' : name;
  97. },
  98. toDetail(id) {
  99. uni.navigateTo({
  100. url: `../../pages/newsDetail/newsDetail?id=${id}`
  101. });
  102. },
  103. formatTitle(title) {
  104. // let phoneArr = title.match(/(0|86|17951)?(13[0-9]|15[0-9]|166|17[3678]|18[0-9]|14[57]|19[0-9])[0-9]{8}/g)
  105. // if(Array.isArray(phoneArr)) {
  106. // phoneArr.map(item => {
  107. // let index = title.indexOf(item)
  108. // let hide_phone = item.replace(item.substring(3,7), "****")
  109. // title = `${title.substr(0, index)}${hide_phone}${title.substr(index + 11)}`
  110. // })
  111. // }
  112. const reg = /1(\d{2})\d{4}(\d{4})/g;
  113. title = title.replace(reg, "1$1****$2");
  114. return title.length > 105 ? title.substring(0, 104) + '...' : title;
  115. },
  116. queryList(pageNo, pageSize) {
  117. //组件加载时会自动触发此方法,因此默认页面加载时会自动触发,无需手动调用
  118. //这里的pageNo和pageSize会自动计算好,直接传给服务器即可
  119. //模拟请求服务器获取分页数据,请替换成自己的网络请求
  120. //let multiSourceType = [2, 4, 1, 3];
  121. let multiSourceType = [1, 4, 2];
  122. const params = {
  123. pageNumber: pageNo,
  124. pageSize: pageSize,
  125. ascription: 1,
  126. multiSource: multiSourceType[this.tabIndex],
  127. title: this.title,
  128. status: 1
  129. };
  130. findPage(params).then(
  131. res => {
  132. if (res.data.state == 200) {
  133. let data = res.data.data.pageRecords.map(item => {
  134. item.clueInfoList = item.clueInfoList.filter(i => {
  135. return i.type !== 0;
  136. });
  137. return item;
  138. });
  139. console.log(data);
  140. this.$refs.paging.complete(data);
  141. } else {
  142. this.$refs.paging.complete([]);
  143. }
  144. this.hideEmptyView = false;
  145. //请求结束,调用父组件的下拉刷新结束回调函数,使得父组件中的z-paging下拉刷新结束
  146. if (this.completeFunc) {
  147. this.completeFunc();
  148. }
  149. },
  150. error => {
  151. this.$refs.paging.complete(false);
  152. if (this.completeFunc) {
  153. this.completeFunc();
  154. }
  155. }
  156. );
  157. },
  158. //页面通知当前子组件刷新列表
  159. reload(completeFunc) {
  160. //先把父组件下拉刷新的回调函数存起来
  161. this.completeFunc = completeFunc;
  162. //调用z-paging的reload方法
  163. this.$refs.paging.reload();
  164. },
  165. //当列表高度改变时,通知页面的swiper同步更改高度
  166. contentHeightChanged(height) {
  167. const finalHeight = this.dataList.length ? height : 0;
  168. this.$emit('heightChanged', finalHeight);
  169. },
  170. //页面通知当前子组件加载更多数据
  171. doLoadMore() {
  172. this.$refs.paging.doLoadMore();
  173. },
  174. //页面通知当前子组件清除数据
  175. clear() {
  176. this.$refs.paging.clear();
  177. this.hideEmptyView = true;
  178. }
  179. }
  180. };
  181. </script>
  182. <style scoped lang="scss">
  183. /* 注意,1、父节点需要固定高度,z-paging的height:100%才会生效 */
  184. /* 注意,2、请确保z-paging与同级的其他view的总高度不得超过屏幕宽度,以避免超出屏幕高度时页面的滚动与z-paging内部的滚动冲突 */
  185. .content {
  186. height: 100%;
  187. }
  188. .item {
  189. .seat {
  190. height: 8px;
  191. width: 100%;
  192. background-color: #f7f7f9;
  193. }
  194. position: relative;
  195. display: flex;
  196. flex-direction: column;
  197. justify-content: space-between;
  198. padding: 0rpx 30rpx;
  199. margin-top: 16px;
  200. .itemTitle {
  201. font-size: 14px;
  202. position: relative;
  203. .allContent {
  204. position: absolute;
  205. bottom: 0;
  206. right: 0;
  207. color: #2468f2;
  208. z-index: 10;
  209. background-color: #ffffff;
  210. }
  211. }
  212. .resources {
  213. display: flex;
  214. flex-wrap: wrap;
  215. margin-top: 8px;
  216. justify-content: space-between;
  217. .resourcesItem {
  218. border-radius: 5px;
  219. overflow: hidden;
  220. position: relative;
  221. margin-bottom: 5px;
  222. .logo {
  223. width: 100%;
  224. height: 100%;
  225. }
  226. .playBtn {
  227. width: 26rpx;
  228. height: 26rpx;
  229. position: absolute;
  230. left: 50%;
  231. top: 50%;
  232. transform: translate(-50%, -50%);
  233. }
  234. }
  235. .resourcesItemOne {
  236. width: 686rpx;
  237. height: 386rpx;
  238. }
  239. .resourcesItems {
  240. width: 218rpx;
  241. height: 218rpx;
  242. }
  243. }
  244. .bottomBox {
  245. margin: 16px 0;
  246. display: flex;
  247. align-items: center;
  248. justify-content: space-between;
  249. font-size: 12px;
  250. color: #5c5f66;
  251. .momentBox {
  252. display: flex;
  253. align-items: center;
  254. .momentImg {
  255. width: 16px;
  256. height: 16px;
  257. margin-right: 4px;
  258. }
  259. .author {
  260. margin-right: 32rpx;
  261. }
  262. }
  263. }
  264. }
  265. .item-detail {
  266. padding: 5rpx 15rpx;
  267. border-radius: 10rpx;
  268. font-size: 28rpx;
  269. color: white;
  270. background-color: #007aff;
  271. }
  272. .item-line {
  273. position: absolute;
  274. bottom: 0rpx;
  275. left: 0rpx;
  276. height: 1px;
  277. width: 100%;
  278. background-color: #eeeeee;
  279. }
  280. </style>