index.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. <template>
  2. <view class="videoPage">
  3. <view class="headerBox">
  4. <view :style="{height: statusBarHeight + 'px'}"></view>
  5. <!-- 头部 -->
  6. <Header />
  7. <!-- 搜索框 -->
  8. <Search />
  9. <!-- 头部导航 -- tab标签 -->
  10. <MenuTab :typeList="typeList" @changeTab="handleSelectTab" />
  11. </view>
  12. <!-- 内容列表 -->
  13. <view class="content">
  14. <scroll-view style="height:100%" :scroll-y="true" :refresher-enabled="true" :refresher-triggered="triggered"
  15. @scrolltolower="scrolltolower" @refresherrefresh="onRefresh" refresher-default-style="black">
  16. <!-- 需要滚动的区域 -->
  17. <view class="videoBox" v-for="item in videoList" :key="item.id" v-if="videoList.length">
  18. <view class="title">
  19. {{item.title}}
  20. </view>
  21. <view class="videoInfo" @click="goDetail(item)">
  22. <image class="bgImg" :src="getUrl(item.picPath)" alt=""></image>
  23. <view class="time">
  24. 04:30
  25. </view>
  26. <view class="func">
  27. <view class="collectCount">
  28. <i class="custom-icon custom-icon-collected"></i>
  29. 2145
  30. </view>
  31. <view class="share" @click.stop="handleShare(item)">
  32. <i class="custom-icon custom-icon-share"></i>
  33. </view>
  34. </view>
  35. </view>
  36. </view>
  37. <!-- 上拉Loading -->
  38. <u-loadmore :status="loadingStatus" marginTop="50px" loadmoreText="没有更多了" line
  39. v-if="showTip && videoList.length" />
  40. <!-- 上拉Loading -->
  41. <u-empty mode="data" text="列表暂无数据" v-if="!videoList.length">
  42. </u-empty>
  43. </scroll-view>
  44. </view>
  45. <!-- 底部导航 -->
  46. <Tabbar :current-page="1" />
  47. <!-- 分享弹出组件 -->
  48. <Share :show="shareShow" @close="closeShare" />
  49. </view>
  50. </template>
  51. <script>
  52. import Header from "@/components/Header/index.vue";
  53. import Search from "@/components/Search/index.vue";
  54. import MenuTab from "@/components/MenuTab/index.vue";
  55. import Tabbar from "@/components/Tabbar/index.vue";
  56. import Share from '@/components/Share/index.vue'
  57. import {
  58. getVideoList,
  59. getVideoType
  60. } from '@/api/video.js'
  61. import {
  62. baseUrl
  63. } from "@/utils/apiconfig.js";
  64. export default {
  65. components: {
  66. Header,
  67. Search,
  68. MenuTab,
  69. Tabbar,
  70. Share
  71. },
  72. data() {
  73. return {
  74. baseUrl,
  75. statusBarHeight: getApp().globalData.statusBarHeight,
  76. typeList: [], // 分类
  77. triggered: false, // 下拉是否激活
  78. loadingStatus: 'loadmore', // 上拉loading
  79. showTip: false, // 是否展示上拉loading
  80. videoList: [],
  81. videoParams: {
  82. pageNum: 1,
  83. pageSize: 10,
  84. // checkStatus: '5', // 已发布的数据
  85. categoryId: '', // 分类
  86. },
  87. total: 0,
  88. pageNum: 1,
  89. pageSize: 10,
  90. isRequesting: false, // 是否正在请求,如果是则返回,用于节流
  91. shareShow: false,
  92. }
  93. },
  94. onLoad() {
  95. this.getType();
  96. this.getList();
  97. },
  98. methods: {
  99. // 获取图片完整地址
  100. getUrl(url) {
  101. return baseUrl + url
  102. },
  103. // 获取视频分类
  104. getType() {
  105. let params = {
  106. status: '0',
  107. pageNum: 1,
  108. pageSize: 9999,
  109. }
  110. getVideoType(params).then(res => {
  111. console.log(res)
  112. let obj = {
  113. id: -1,
  114. name: '全部'
  115. }
  116. this.typeList = [obj, ...res.rows]
  117. })
  118. },
  119. // 切换tab
  120. handleSelectTab(val) {
  121. // 切换tab时页面要回到顶部
  122. uni.pageScrollTo({
  123. scrollTop: 0,
  124. duration: 0, // 直接跳转到顶部,不需要动画
  125. })
  126. this.videoParams = {
  127. ...this.videoParams,
  128. pageNum: 1,
  129. categoryId: val.id === -1 ? '' : val.id,
  130. }
  131. this.getList()
  132. },
  133. // 上拉加载
  134. scrolltolower() {
  135. this.showTip = true
  136. if (this.videoList.length < this.total) {
  137. this.pageNum += 1;
  138. // 继续请求下一页,记得保留原先数组
  139. this.getList();
  140. } else {
  141. uni.showToast({
  142. title: "没有更多了",
  143. icon: "none",
  144. duration: 2000,
  145. });
  146. return;
  147. }
  148. },
  149. // 自定义下拉刷新被触发
  150. onRefresh() {
  151. // 开启下拉自定义样式
  152. this.triggered = true;
  153. // 清空原本的列表数据。不然会叠加
  154. this.videoList = [];
  155. // 重新调用
  156. this.getList();
  157. // 1秒之后复位
  158. setTimeout(() => {
  159. this.triggered = false;
  160. }, 1000);
  161. },
  162. getList() {
  163. this.isRequesting = true
  164. getVideoList(this.videoParams).then(res => {
  165. // console.log("res:", res)
  166. this.videoList = [...this.videoList, ...res.rows]
  167. // console.log('videoList', this.videoList)
  168. this.total = res.total
  169. this.loadingStatus = this.videoList.length >= this.total ? 'nomore' : 'loading'
  170. }).finally(() => this.isRequesting = false)
  171. },
  172. // 点击资讯跳转详情
  173. goDetail(val) {
  174. console.log('跳转')
  175. uni.navigateTo({
  176. url: '/pages/video/detail'
  177. });
  178. },
  179. // 点击弹出分享框
  180. handleShare(val) {
  181. console.log(111)
  182. this.shareShow = true
  183. },
  184. // 关闭分享弹出窗
  185. closeShare() {
  186. this.shareShow = false
  187. },
  188. }
  189. }
  190. </script>
  191. <style lang="scss" scoped>
  192. page {
  193. background-color: #f9f9f9;
  194. font-size: 28rpx;
  195. height: 100%;
  196. // background-color: yellow;
  197. }
  198. .videoPage {
  199. height: 100vh;
  200. padding-top: 20rpx;
  201. display: flex;
  202. flex-direction: column;
  203. /deep/ .Search {
  204. margin: 20rpx 0;
  205. }
  206. .content {
  207. min-height: 0;
  208. flex: 1;
  209. box-sizing: border-box;
  210. // background-color: yellow;
  211. overflow-y: auto;
  212. position: relative;
  213. /deep/ .u-loadmore {
  214. padding-bottom: 200rpx;
  215. }
  216. /deep/ .u-empty {
  217. position: absolute;
  218. left: 50%;
  219. transform: translate(-50%, 50%);
  220. }
  221. }
  222. .videoBox {
  223. margin: 20rpx auto;
  224. width: 100%;
  225. // display: flex;
  226. // justify-content: space-between;
  227. padding: 0 40rpx;
  228. .title {
  229. // font-size: 32rpx;
  230. margin-bottom: 20rpx;
  231. font-weight: 600;
  232. color: #666;
  233. }
  234. .videoInfo {
  235. border-radius: 30rpx;
  236. height: 360rpx;
  237. position: relative;
  238. .bgImg {
  239. position: absolute;
  240. z-index: -1;
  241. width: 100%;
  242. height: 100%;
  243. }
  244. .time {
  245. color: #fff;
  246. position: absolute;
  247. top: 20rpx;
  248. right: 20rpx;
  249. width: 100rpx;
  250. height: 50rpx;
  251. text-align: center;
  252. line-height: 50rpx;
  253. border-radius: 50rpx;
  254. background-color: rgba(255, 255, 255, 0.5);
  255. }
  256. .func {
  257. width: 100%;
  258. position: absolute;
  259. bottom: 0;
  260. left: 0;
  261. display: flex;
  262. justify-content: space-between;
  263. padding: 28rpx 40rpx;
  264. .collectCount,
  265. .share {
  266. height: 100rpx;
  267. background-color: #fff;
  268. text-align: center;
  269. line-height: 100rpx;
  270. border-radius: 20rpx;
  271. .custom-icon {
  272. &::before {
  273. background: -webkit-linear-gradient(left, #f84a1a, #f79234);
  274. -webkit-background-clip: text;
  275. -webkit-text-fill-color: transparent;
  276. font-weight: bold;
  277. }
  278. }
  279. }
  280. .collectCount {
  281. padding: 0 20rpx;
  282. display: flex;
  283. align-items: center;
  284. .custom-icon {
  285. margin-right: 10rpx;
  286. }
  287. }
  288. .share {
  289. padding: 0 40rpx;
  290. .custom-icon {
  291. font-size: 24rpx;
  292. }
  293. }
  294. }
  295. }
  296. }
  297. }
  298. </style>