定制开发vue实现列表自动滚动的方式(一)

      定制开发虽然是标题是《vue定制开发实现列表自动滚动的方式》,定制开发但其它应该也可以通过定制开发这种方式实现,定制开发本案例中没有使用任何定制开发第三方插件,全部使用vue中相关的js、css定制开发以及定时器方式实现。

      定制开发解决问题的第一步不是找代码,定制开发而是分析问题。定制开发列表自动滚动常见方式有两种(定制开发上下左右的滚动不赘述,定制开发只是方向的问题,定制开发本案例以向上自动滚动为例):(1)匀速滚动   (2)定制开发有间隔的平滑滚动。定制开发本案例先给出匀速滚动的方案。

     这篇文章是原创,代码是项目中自己编写的,所以运行肯定没有问题。

     要匀速向上滚动,以我的经验,最容易想到的是用定时器实现,每隔一个时间差,列表向上移动一个像素(大于一个像素,可能会在视觉上给人卡顿掉帧的感觉),在时间够短的前提下,就会给人一种匀速向上的感觉。然后需要考虑列表衔接的问题,列表再长也有尽头,需要考虑滚动到最后一条数据出现时的问题。

     我给出的方案是,在列表的末尾拼接一个同样内容的列表,形成长度为原列表两倍的列表(如果考虑性能问题,在原列表后拼接上原列表的前几条数据就可以,具体几条根据滚动可视范围内的最大完整数据条数而定,具体往下看就明白了),然后当拼接列表滚动到可视范围内的内容和初始状态一致时(即拼接列表的上半段的最后一条记录向上滚动至完全消失时),将拼接列表向上滚动的距离归零,即可在视觉上给人一种匀速向上,且无限循环的感觉。

     先上定时器这块方法的代码。

  1. //根据列表长度是否超过可视范围内能够显示的最大完整数据条数,来控制列表是否需要滚动
  2. tableActionFun() {
  3. this.tableListSize = this.tableList.length;
  4. //下面的visibleSize是可视范围内能够显示的最大完整数据条数
  5. if (this.tableListSize > this.visibleSize) {
  6. this.tableList = this.tableList.concat(this.tableList);
  7. this.tableTimerFun(); //列表滚动方法
  8. } else {
  9. this.fillTableList(); //无需滚动时的数据填充方法,如果没必要,可以删掉
  10. }
  11. },
  12. //列表滚动方法
  13. tableTimerFun() {
  14. var count = 0;
  15. this.tableTimer = setInterval(() => {
  16. if (count < (this.tableList.length / 2) * this.lineHeight) {
  17. this.tableTop -= 1;
  18. count++;
  19. } else {
  20. count = 0;
  21. this.tableTop = 0;
  22. }
  23. }, this.tableTimerInterval);
  24. },

      上面的代码段中提到了可视范围内能够显示的最大完整数据条数 visibleSize,直接上案例里的截图,一看就明白了。截图中可以看到第一条数据和最后一条数据并没有完全显示,因为他们超出父容器的部分被 overflow: hidden 了,所以案例中的 visibleSize = 6. 

     所以本案例是通过列表不断上移,父容器隐藏超出部分来实现列表自动迅速滚动的。讲解的过程中可能有遗漏,直接上完整代码,重要部分都写了注释。下面的代码直接粘贴运行不会运行成功,因为下面的完整代码涉及接口调用,但所有功能已经一步到位,希望在看的你能通过注释更多地去理解,而不是简单地复制粘贴。希望能对你有所帮助。

  1. <template>
  2. <div class="productProcess">
  3. <!-- 如果页面刷新数据比较频繁,可以将loading、showFlag的相关代码删除,防止过于频繁的出现加载动画 -->
  4. <div class="loading_div" v-show="!showFlag">
  5. <div>Loading...</div> <!-- 这个loading自己写,代码没贴出来 -->
  6. </div>
  7. <div class="success_info_body" v-show="showFlag">
  8. <!-- 标准title可以调用组件 -->
  9. <div class="title_div">
  10. <!-- <titleComponent :title="title"></titleComponent> --> <!-- 标题组件自己写,代码没贴出来 -->
  11. </div>
  12. <!-- 参数名称、列数根据实际情况调整 -->
  13. <div class="table_body">
  14. <div class="table_th">
  15. <div class="tr1 th_style">排产编号</div>
  16. <div class="tr2 th_style">类型</div>
  17. <div class="tr3 th_style">日期</div>
  18. <div class="tr4 th_style">进度</div>
  19. </div>
  20. <div class="table_main_body">
  21. <div class="table_inner_body" :style="{top: tableTop + 'px'}">
  22. <div class="table_tr" v-for="(item,index) in tableList" :key="index">
  23. <div class="tr1 tr">{{item.planNo}}</div>
  24. <div class="tr2 tr">{{item.type}}</div>
  25. <div class="tr3 tr" v-if="item.startDate!='-'">{{item.startDate}} ~ {{item.endDate}}</div>
  26. <div class="tr3 tr" v-else>-</div>
  27. <div class="tr4 tr" v-if="item.process!='-'">{{Number(item.process).toFixed(2)}} %</div>
  28. <div class="tr4 tr" v-else>-</div>
  29. </div>
  30. </div>
  31. </div>
  32. </div>
  33. </div>
  34. </div>
  35. </template>
  36. <script>
  37. import titleComponent from "@/components/titleComponent";
  38. export default {
  39. components: {
  40. titleComponent
  41. },
  42. data() {
  43. return {
  44. showFlag: true,
  45. tableTimer: null,
  46. tableTop: 0,
  47. tableList: [],
  48. /* tableList 参考格式
  49. [{
  50. "process":0.0000,
  51. "planNo":"BP2022060701",
  52. "endDate":"2022-06-07",
  53. "type":"砌块",
  54. "startDate":"2022-06-07"
  55. },
  56. {
  57. "process":0.0000,
  58. "planNo":"WP2022061301",
  59. "endDate":"2022-06-13",
  60. "type":"墙板",
  61. "startDate":"2022-06-13"
  62. }]
  63. */
  64. tableListSize: 0,
  65. componentTimer: null,
  66. //需要根据情况设置的参数
  67. title: "排产进度",
  68. visibleSize: 6, //容器内可视最大完整行数
  69. lineHeight: 49, //每行的实际高度(包含margin-top/bottom,border等)
  70. componentTimerInterval: 3600000, //刷新数据的时间间隔
  71. tableTimerInterval: 100 //向上滚动 1px 所需要的时间,越小越快,推荐值 100
  72. };
  73. },
  74. //如果没有父元素传值,将watch内的内容搬至mounted中即可
  75. props: ["activeFactoryId"],
  76. watch: {
  77. activeFactoryId(val, oldVal) {
  78. clearInterval(this.componentTimer);
  79. this.bsGetProductProcess();
  80. this.componentTimerFun();
  81. }
  82. },
  83. mounted() {
  84. },
  85. beforeDestroy() {
  86. clearInterval(this.componentTimer);
  87. clearInterval(this.tableTimer);
  88. },
  89. methods: {
  90. //调用数据接口,获取列表数据,根据自己情况填接口url
  91. bsGetProductProcess() {
  92. clearInterval(this.tableTimer);
  93. this.tableTop = 0;
  94. if (this.activeFactoryId != "") {
  95. this.showFlag = false;
  96. this.$ajax({
  97. method: "get",
  98. url: `` //根据自己情况填接口url
  99. })
  100. .then(res => {
  101. this.tableList = res.data.data;
  102. this.showFlag = true;
  103. this.tableActionFun();
  104. })
  105. .catch(function(err) {
  106. console.log("bsGetProductProcess error!");
  107. });
  108. }
  109. },
  110. tableActionFun() {
  111. this.tableListSize = this.tableList.length;
  112. if (this.tableListSize > this.visibleSize) {
  113. this.tableList = this.tableList.concat(this.tableList);
  114. this.tableTimerFun();
  115. } else {
  116. this.fillTableList();
  117. }
  118. },
  119. //当数据过少时,不触发自动轮播事件,并填充没有数据的行,参数根据实际情况修改即可
  120. fillTableList() {
  121. var addLength = this.visibleSize - this.tableListSize;
  122. for (var i = 0; i < addLength; i++) {
  123. this.tableList.push({
  124. planNo: "-",
  125. type: "-",
  126. startDate: "-",
  127. endDate: "-",
  128. process: "-"
  129. });
  130. }
  131. },
  132. tableTimerFun() {
  133. var count = 0;
  134. this.tableTimer = setInterval(() => {
  135. if (count < (this.tableList.length / 2) * this.lineHeight) {
  136. this.tableTop -= 1;
  137. count++;
  138. } else {
  139. count = 0;
  140. this.tableTop = 0;
  141. }
  142. }, this.tableTimerInterval);
  143. },
  144. componentTimerFun() {
  145. this.componentTimer = setInterval(() => {
  146. this.bsGetProductProcess();
  147. }, this.componentTimerInterval);
  148. }
  149. }
  150. };
  151. </script>
  152. <style scoped>
  153. .productProcess {
  154. width: 550px;
  155. height: 415px;
  156. }
  157. .loading_div {
  158. color: #eee;
  159. padding-top: 100px;
  160. }
  161. .title_div {
  162. width: 100%;
  163. }
  164. .table_body {
  165. width: 100%;
  166. margin-top: 15px;
  167. }
  168. .table_th {
  169. width: 100%;
  170. display: flex;
  171. height: 40px;
  172. line-height: 40px;
  173. }
  174. .tr {
  175. overflow: hidden;
  176. text-overflow: ellipsis;
  177. white-space: nowrap;
  178. box-sizing: border-box;
  179. padding: 0 5px;
  180. text-align: center;
  181. font-size: 14px;
  182. }
  183. .tr1 {
  184. width: 28%;
  185. }
  186. .tr2 {
  187. width: 15%;
  188. }
  189. .tr3 {
  190. width: 35%;
  191. font-size: 13px;
  192. }
  193. .tr4 {
  194. flex: 1;
  195. }
  196. .th_style {
  197. color: rgb(0, 221, 253);
  198. font-weight: bold;
  199. font-size: 18px;
  200. overflow: hidden;
  201. text-overflow: ellipsis;
  202. white-space: nowrap;
  203. box-sizing: border-box;
  204. padding: 0 5px;
  205. text-align: center;
  206. }
  207. .table_main_body {
  208. width: 100%;
  209. height: 294px;
  210. overflow: hidden;
  211. position: relative;
  212. }
  213. .table_inner_body {
  214. width: 100%;
  215. position: absolute;
  216. left: 0;
  217. }
  218. .table_tr {
  219. display: flex;
  220. height: 40px;
  221. line-height: 40px;
  222. color: #eee;
  223. font-size: 15px;
  224. background: rgba(3, 145, 167, 0.1);
  225. border: 1px solid rgb(4, 114, 131);
  226. margin-top: 7px;
  227. }
  228. </style>

      最后是效果视频。

     下一篇文章将讲解有间隔的平滑滚动如何实现,虽然同样会使用到定时器,但会更多的使用到css的一些功能。

     大家若有什么疑问或者有其它想法可以在评论区留言,我会尽量解答和回复的。

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发