index.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <template>
  2. <view class="lsv-container">
  3. <mescroll-uni
  4. ref="mescrollRef"
  5. :fixed="false"
  6. :up="upOption"
  7. :down="downOption"
  8. @up="upCallback"
  9. @down="downCallback"
  10. @init="mescrollInit"
  11. @scroll="onScroll">
  12. <view class="lsv-list">
  13. <slot name="list" :data="dataList" :is-scrolling="isScrolling"></slot>
  14. </view>
  15. </mescroll-uni>
  16. </view>
  17. </template>
  18. <script>
  19. export default {
  20. name: '',
  21. props: {
  22. // 数据接口
  23. api: {
  24. type: Object,
  25. required: true,
  26. default: null
  27. },
  28. // 初始参数
  29. init: {
  30. type: Object,
  31. default: () => ({})
  32. },
  33. emptyText: {
  34. type: String,
  35. default: ''
  36. },
  37. emptyBtnText: {
  38. type: String,
  39. default: ''
  40. },
  41. // 自定义list数据的字段
  42. keyName: {
  43. type: String,
  44. default: 'records'
  45. },
  46. // page相关
  47. noPage: {
  48. type: Boolean,
  49. default: false
  50. },
  51. pageSize: {
  52. type: [Number, String],
  53. default: 10
  54. },
  55. },
  56. data() {
  57. return {
  58. params: {},
  59. dataList: [],
  60. // 下拉刷新的配置
  61. downOption: {
  62. },
  63. // 是否滚动
  64. isScrolling: false,
  65. scrollTimer: null
  66. };
  67. },
  68. computed: {
  69. // 上拉加载的配置
  70. upOption() {
  71. let obj = {
  72. // noMoreSize: 5, // 如果列表已无数据,可设置列表的总数量要大于5条才显示无更多数据;
  73. onScroll: true,
  74. textNoMore: '-- 暂无更多数据 --',
  75. page: {
  76. size: this.pageSize // 每页数据的数量,默认10
  77. },
  78. empty: {
  79. use: true,
  80. tip: this.emptyText || '暂无数据',
  81. btnText: this.emptyBtnText,
  82. // icon: '/static/common/empty.png',
  83. }
  84. };
  85. return obj;
  86. }
  87. },
  88. methods: {
  89. // scroll
  90. mescrollInit(e) {
  91. this.mescroll = e;
  92. },
  93. onScroll(e) {
  94. this.isScrolling = true;
  95. // 使用防抖判断滚动结束
  96. clearTimeout(this.scrollTimer);
  97. this.scrollTimer = setTimeout(() => {
  98. this.isScrolling = false;
  99. }, 200);
  100. },
  101. // 下拉刷新
  102. downCallback() {
  103. this.mescroll.resetUpScroll();
  104. },
  105. // 上拉加载
  106. upCallback(e) {
  107. if (!this.api) {
  108. this.mescroll.endErr();
  109. return;
  110. }
  111. let options = {}, params = {
  112. pageNo: e.num,
  113. pageSize: e.size,
  114. ...this.init,
  115. ...this.params
  116. };
  117. // request底层问题
  118. if (this.api.method === 'POST') {
  119. options.data = params;
  120. } else if (this.api.method === 'GET') {
  121. options.params = params;
  122. }
  123. // 置空
  124. if(e.num == 1) this.dataList = [];
  125. // 请求
  126. this.$http.request({
  127. ...this.api,
  128. ...options
  129. }).then(res => {
  130. if (res.data.code === 200) {
  131. let r = res.data.result;
  132. // 无分页处理,用于那些需要下拉和空列表的地方
  133. if (this.noPage) {
  134. r = {
  135. records: r,
  136. total: r.length
  137. };
  138. }
  139. let result = r || {}, records = r[this.keyName] || [];
  140. this.$emit('afterFetch', result);
  141. // 数据
  142. this.dataList = this.dataList.concat(records);
  143. this.mescroll.endBySize(records.length, result.total || result[this.keyName].total);
  144. } else {
  145. this.$tip.error(res.data.message || '数据请求发生错误');
  146. this.mescroll.endErr();
  147. }
  148. }).catch(e => {
  149. this.mescroll.endErr();
  150. });
  151. },
  152. reloadList(p) {
  153. this.params = p;
  154. this.mescroll.resetUpScroll();
  155. }
  156. }
  157. }
  158. </script>
  159. <style lang="scss" scoped>
  160. .lsv-container {
  161. height: 100%;
  162. position: relative;
  163. .lsv-list {
  164. min-height: 100%;
  165. }
  166. }
  167. </style>