Home.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <template>
  2. <div class="report-home" ref="wrapper">
  3. <div v-if="listState.list.length && listState.list.length > 0">
  4. <van-pull-refresh v-model="isLoading" @refresh="onRefresh">
  5. <van-list
  6. v-model="listState.loading"
  7. :finished="listState.finished"
  8. :immediate-check="false"
  9. finished-text="没有更多了"
  10. @load="onLoad"
  11. :offset="50"
  12. >
  13. <ul class="list">
  14. <li class="item" v-for="item in listState.list" :key="item.id" @click="goDetail(item)">
  15. <div class="item-img">
  16. <img :src="item.img" alt="">
  17. </div>
  18. <div class="item-cont">
  19. <p class="ellipsis-2 title">{{item.title}}</p>
  20. <div class="desc">
  21. <div class="left">{{item.publishtime* 1000 | dateFormatter('yyyy/MM/dd')}}</div>
  22. <div class="right">
  23. <span class="before-price">&yen; <em>{{item.before_price | fen2Yuan}}</em></span>
  24. <span class="current-price">&yen; <em>{{item.price | fen2Yuan}}</em> </span>
  25. </div>
  26. </div>
  27. </div>
  28. </li>
  29. </ul>
  30. </van-list>
  31. </van-pull-refresh>
  32. </div>
  33. <Empty v-else>
  34. <div class="tip-sub-text">暂无数据</div>
  35. </Empty>
  36. </div>
  37. </template>
  38. <script lang="ts">
  39. import { Component, Vue } from 'vue-property-decorator'
  40. import { mapState, mapMutations, mapActions } from 'vuex'
  41. import { PullRefresh, List, Toast } from 'vant'
  42. import Empty from '@/components/common/Empty.vue'
  43. @Component({
  44. name: 'home',
  45. components: {
  46. [PullRefresh.name]: PullRefresh,
  47. [List.name]: List,
  48. Empty
  49. },
  50. methods: {
  51. ...mapState('home', {
  52. reportList: (state: any) => state.reportList
  53. }),
  54. ...mapMutations({
  55. saveList: 'home/saveReportList',
  56. clearList: 'home/clearReportList'
  57. }),
  58. ...mapActions({
  59. getList: 'home/getReportList'
  60. })
  61. }
  62. })
  63. export default class Home extends Vue {
  64. protected reportList!: any
  65. protected getList!: any
  66. protected saveList!: any
  67. protected clearList!: any
  68. isLoading = false
  69. listState = {
  70. list: [],
  71. loading: false,
  72. finished: false,
  73. currentPage: 1,
  74. totalPage: 0,
  75. scroll: 0
  76. }
  77. beforeRouteEnter (to, from, next) {
  78. if (from.name === 'detail') {
  79. to.meta.isBack = true
  80. } else {
  81. to.meta.isBack = false
  82. }
  83. next()
  84. }
  85. activated () {
  86. if (!this.$route.meta.isBack) {
  87. this.listState = {
  88. list: [],
  89. loading: false,
  90. finished: false,
  91. currentPage: 1,
  92. totalPage: 0,
  93. scroll: 0
  94. }
  95. this.getReportList()
  96. return
  97. }
  98. this.$route.meta.isBack = false
  99. this.listState = this.reportList()
  100. this.$nextTick(() => {
  101. ;(this.$refs.wrapper as any).scrollTop = this.reportList().scroll
  102. })
  103. }
  104. beforeRouteLeave (to, form, next) {
  105. this.listState.scroll = (this.$refs.wrapper as any).scrollTop
  106. this.saveList(this.listState)
  107. next()
  108. }
  109. getReportList (type = 'load') {
  110. this.listState.loading = true
  111. this.getList(`page_index=${this.listState.currentPage}`).then((res: any) => {
  112. if (res.error_code === 0 && res.data.list) {
  113. const rows = res.data.list
  114. this.listState.loading = false
  115. this.listState.totalPage = res.data.page_count
  116. if (rows === null || rows.length === 0) {
  117. this.listState.finished = true
  118. return
  119. }
  120. if (this.listState.currentPage >= this.listState.totalPage) {
  121. this.listState.finished = true
  122. }
  123. if (this.listState.currentPage === 1) {
  124. if (type === 'refresh') {
  125. this.isLoading = false
  126. Toast({ message: '刷新成功', duration: 1000 })
  127. }
  128. this.listState.list = rows
  129. } else {
  130. this.listState.list = this.listState.list.concat(rows)
  131. }
  132. } else {
  133. this.listState.finished = true
  134. }
  135. }).catch(() => {
  136. this.listState.finished = true
  137. })
  138. }
  139. onLoad () {
  140. if (this.listState.currentPage < this.listState.totalPage) {
  141. this.listState.currentPage++
  142. this.getReportList()
  143. }
  144. }
  145. goDetail (item) {
  146. this.$router.push(`/detail/${item.id}`)
  147. }
  148. onRefresh () {
  149. this.clearList(this.listState)
  150. this.listState.loading = false
  151. this.listState.finished = false
  152. this.listState.currentPage = 1
  153. this.listState.totalPage = 0
  154. this.listState.scroll = 0
  155. this.$nextTick(() => {
  156. this.getReportList('refresh')
  157. })
  158. }
  159. }
  160. </script>
  161. <style lang="scss">
  162. .report-home {
  163. .list{
  164. .item{
  165. position: relative;
  166. display: flex;
  167. padding: 20px 16px;
  168. background-color: #fff;
  169. &:after{
  170. position: absolute;
  171. box-sizing: border-box;
  172. content: ' ';
  173. pointer-events: none;
  174. right: 16px;
  175. bottom: 0;
  176. left: 16px;
  177. border-bottom: 1px solid rgba(0, 0, 0, 0.02);
  178. // -webkit-transform: scaleY(0.5);
  179. // transform: scaleY(0.5);
  180. }
  181. .item-img{
  182. width: 80px;
  183. height: 80px;
  184. border-radius: 4px;
  185. margin-right: 16px;
  186. overflow: hidden;
  187. img{
  188. width: 100%;
  189. height: 100%;
  190. }
  191. }
  192. .item-cont{
  193. flex: 1;
  194. .title{
  195. font-size: 16px;
  196. line-height: 24px;
  197. color: #171826;
  198. }
  199. .desc{
  200. display: flex;
  201. justify-content: space-between;
  202. align-items: center;
  203. margin-top: 13px;
  204. .left{
  205. font-size: 12px;
  206. line-height: 18px;
  207. color: #9B9CA3;
  208. }
  209. .right{
  210. display: flex;
  211. align-items: center;
  212. }
  213. .before-price{
  214. font-size: 12px;
  215. line-height: 18px;
  216. color: #9B9CA3;
  217. margin-right: 6px;
  218. em{
  219. text-decoration: line-through;
  220. }
  221. }
  222. .current-price{
  223. display: flex;
  224. align-items: center;
  225. color: #FB483D;
  226. font-size: 14px;
  227. line-height: 20px;
  228. em{
  229. margin-left: 2px;
  230. font-size: 16px;
  231. line-height: 24px;
  232. }
  233. }
  234. }
  235. }
  236. }
  237. }
  238. }
  239. </style>