There are two requirements in the recent project (vue Series). Here is a record to share with you.
Polling by native Table list
Demand:
- Do not poll when the number of table lists is small, and only poll when the number exceeds a certain height;
- Move the mouse in to pause polling, move out to continue polling
First, the prototype is as follows:
There is a paging in the lower right corner. It uses the paging component of the elementUI. After changing the style, the main body is a native table
There are several ways to implement polling. There are many ways to search and search on the Internet. I use js here. The general idea is to control margin top, such as margin top = - 1px, margin top = - 2px; margin top = - 3px;. When the value is greater than the row height, it means that the data has been scrolled. At this time, recover margin top = 0 and insert it into the bottom of tbody to implement polling . Direct code:
HTML
<div class="network-container"> <div class="network-center"> <img src="./imgs/img_map_bg_02.png" /> <img src="./imgs/img_map_bg_04.png" /> <div class="network-center-content"> <table class="deviceInfoBox"> <thead> <tr> <th class="name">Equipment type</th> <th class="name">Major categories of equipment</th> <th class="code">Equipment number</th> <th class="pos">Device location</th> <th class>Task delay</th> <th class="sysState">Device status</th> <th class="pro">Task completion progress</th> <th class="pro">Task start time</th> <th class="pro">Task end time</th> <th class="pro">Task duration</th> </tr> </thead> </table> <div class="scroll-box" ref="scrollBox"> <table class="tab-scroll" ref="scroll" @mouseenter="activeEve(false)" @mouseleave="activeEve(true)" > <tbody> <tr v-for="(si,idx) in deviceInfoList" :key="idx"> <td class="name">{{si.name || '-'}}</td> <td class="type">{{si.type || '-'}}</td> <td class="code"> <a @click="handleClick(si)" :class="{'isDisabled':(si.name !== 'Concrete ceiling grinding') || si.sysState !== '3'}" >{{si.deviceCode || '-'}}</a> </td> <td class="pos">{{si.posistion || '-'}}</td> <td class="pos" v-if="si.sysState == '3'">{{Number(si.delayedTime)+'ms'}}</td> <td class="pos" v-else>{{si.delayedTime || '-'}}</td> <td class="sysState" :class="{'yellow': si.sysState == '2', 'green': si.sysState == '3'}" >{{deviceStateArr[si.sysState] || '-'}}</td> <td v-if="si.sysState == '3'"> <el-progress :percentage="si.progress || 0"></el-progress> </td> <td v-else>{{si.progress || '-'}}</td> <td>{{si.workStartTime || '-'}}</td> <td>{{si.workEndTime || '-'}}</td> <td>{{si.duration}}</td> </tr> </tbody> </table> </div> </div> <div class="page-bar"> <el-pagination background layout="prev,pager, next" :current-page="page" :page-size="pageSize" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" ></el-pagination> </div> </div> </div> </template>
CSS
<style scoped lang='scss'> table { width: 100%; table-layout: fixed; border-collapse: collapse; } th, td { line-height: 35px; color: #ffffff; text-align: center; word-break: keep-all; /* nowrap */ white-space: nowrap; /* nowrap */ overflow: hidden; /* Hide excess content when content exceeds width */ text-overflow: ellipsis; /* for IE */ } .scroll-box { width: 100%; height: 100%; overflow: hidden; position: relative; } .tab-scroll { table-layout: fixed; font-size: 16px; position: absolute; left: 0; top: 0; border-top: none; padding-left: 60px; .isDisabled { pointer-events: none; cursor: not-allowed; } .yellow { color: #dada09; } .green { color: #04ba19; } } .left-button { position: absolute; left: 4px; padding: 24px 14px; top: 50%; transform: translate(0, -50%); width: 46px; height: 221px; color: #fff; text-align: center; line-height: 26px; font-size: 18px; z-index: 100; border: solid 1px #31467d; border-left: none; color: #65c6e7; } .show { background: url('../../../assets/dashboard/icon_packup.png'); width: 12px; height: 14px; transform: rotate(180deg); display: inline-block; background-size: contain; } .hide { background: url('../../../assets/dashboard/icon_packup.png'); width: 12px; height: 14px; display: inline-block; background-size: contain; } .deviceInfoBox { table-layout: fixed; font-size: 16px; color: #fff; width: 100%; z-index: 50; text-align: center; transition: 500ms all ease-in; th { color: #65c6e7; white-space: nowrap; } td { color: #ffffff; white-space: nowrap; } .yellow { color: #dada09; } .green { color: #04ba19; } } .flex-row-center { display: flex; flex-direction: row; align-items: center; } .flex-row { display: flex; flex-direction: row; } .flex-col-center { display: flex; flex-direction: column; justify-content: center; } .network-container { height: 100%; overflow: auto; min-width: 38.4rem; background: url('./imgs/img_bg.png') no-repeat; background-size: 100% 100%; font-size: 50px; display: flex; flex-direction: column; height: 100%; width: 100%; > div { width: 100%; } .network-center { position: relative; margin: 0.2rem 0.4rem 0 0.4rem; width: calc(100% - 0.8rem); min-height: 9.64rem; flex: 1; overflow: hidden; &:before { content: ''; display: block; height: 0.5rem; width: 0.5rem; position: absolute; background: url('./imgs/img_map_bg_01.png') no-repeat; background-size: 100% 100%; left: 3px; top: 3px; z-index: 99; } img { position: absolute; background-size: 100% 100%; height: 0.5rem; width: 0.5rem; z-index: 99; } > img:nth-child(1) { right: 3px; top: 3px; } > img:nth-child(2) { right: 3px; bottom: 2px; } &:after { content: ''; height: 0.5rem; width: 0.5rem; position: absolute; background: url('./imgs/img_map_bg_03.png') no-repeat; background-size: 100% 100%; bottom: 2px; left: 3px; z-index: 99; } .network-center-content { border: solid 0.02rem #31467d; width: calc(100% - 0.12rem); height: 100%; margin: 0.06rem; overflow: hidden; padding-left: 60px; } .page-bar { position: absolute; right: 0; bottom: 0; margin-right: 10px; margin-bottom: 10px; /deep/.el-pagination.is-background .btn-prev, /deep/.el-pagination.is-background .btn-next, /deep/.el-pagination.is-background .el-pager li { background-color: #04162a; border: solid 1px #31467d; color: #2bfaff; margin: 0 3px; } /deep/.el-pagination.is-background .el-pager li:not(.disabled).active { background-color: #43d5d7; } } } } </style>
JS
table polling method:
methods: { activeEve(val) { this.scroll = val const self = this, wrapH = this.$refs.scrollBox.clientHeight, sel = this.$refs.scroll, tbody = sel.children[0], tbodyH = tbody.clientHeight let timer_s = null, step = 0 if (this.scroll && tbodyH > wrapH) { if (self.timer) clearTimeout(self.timer) cycle() } else { if (self.timer) clearTimeout(self.timer) } function cycle() { if (self.timer) clearTimeout(self.timer) self.timer = setTimeout(function() { scroll() }, 2000) } function scroll() { cancelAnimationFrame(timer_s) timer_s = requestAnimationFrame(function fn() { if (!tbody.children || !tbody.children.length) return const trH = tbody.children[0].clientHeight if (Math.abs(step) > trH) { cancelAnimationFrame(timer_s) step = 0 sel.style.marginTop = 0 tbody.appendChild(tbody.firstChild) cycle() } else { step-- sel.style.marginTop = `${step}px` timer_s = requestAnimationFrame(fn) } }) } } }
At this point, the table polling function has been implemented.
After a period of time, the boss said that he didn't need to poll first and replaced it with a scroll bar.
css modifying the default scroll bar style
On the original basis, it can be implemented with only a little change. Here is the implementation of css:
css
.scroll-box { width: 100%; height: 510px; overflow: hidden; overflow-y: scroll; position: relative; // Change the default scroll bar style // Change the default scroll bar style &::-webkit-scrollbar {/*Scroll bar overall style*/ width: 6px; /*Height and width correspond to the size of horizontal and vertical scroll bars respectively*/ height: 6px; background: transparent; } &::-webkit-scrollbar-thumb {/*Small square in scroll bar*/ background: transparent; border-radius: 4px; } &:hover::-webkit-scrollbar-thumb { background: hsla(0, 0%, 53%, 0.4); } &:hover::-webkit-scrollbar-track {/*Inner track of scroll bar*/ background: hsla(0, 0%, 53%, 0.1); } // If you need to poll the table, please comment out the above and release the following width: 100%; height: 100%; overflow: hidden; position: relative; }
OK, that's OK. It will appear when the mouse is moved in. The following is the effect: