background
Recently, we are developing a large-screen visualization project. In addition to various
echarts
charts and map displays, there are also multiple tables. Now there is a requirement to set all tables in the large screen to seamless scrolling of content.
Based on the seven deadly sins of programmers, I tried to shirk it for the first time, but failed.
- After simply checking on the Internet, there are two options suitable for our project. The first one is to use a plug-in vue3-seamless-scroll.
- The second option is to write JS code yourself to control the automatic scrolling of the table scroll bar through a timer.
Option One
From the actual development point of view, it would be best to consider using plug-ins that have similar functions and can be used out of the box without any problems. It can improve a lot of work efficiency and achieve the goal of getting off work on time.
vue3-seamless-scroll(Click to enter the official documentation)
According to the plug-in description, the current component supports seamless scrolling up, down, left, and right, single-step scrolling, and supports seamless scrolling of complex icons. The supported platform is consistent with the Vue3.0 supported platform.
Install
npm
npm install vue3-seamless-scroll --save
yarn
yarn add vue3-seamless-scroll
browser
<script src="https://unpkg.com/browse/[email protected]/dist/vue3-seamless-scroll.min.js"></script>
Configuration
- list
Seamlessly scrolls list data, using the list length internally in the component.
type: Array
required: true
- v-model
Control animation scrolling and stopping through v-model, start scrolling by default
type: Boolean
default: true
required: false
- direction
Control the scrolling direction, optional values are up, down, left, right
type: String
default: “up”< a i=3> required: false
- isWatch
Turn on data update monitoring
type: Boolean,
default: true,
required: false
- hover
Whether to enable mouse hover
type: Boolean
default: false
required: false
- count
Number of animation loops, default infinite loop
type: Number
default: “infinite”
required: false
- limitScrollNum
The amount of data to enable scrolling, only the list length is greater than or equal to this value will scroll
type: Number,
default: 5,
required: false
- step
步进速度
type: Number,
required: false
- singleHeight
The height at which single-step motion stops
type: Number,
default: 0,
required: false< /span>
- singleWidth
Single-step motion stop width
type: Number,
default: 0,
required: false< /span>
- singleWaitTime
Single-step stop waiting time (default value 1000ms)
type: Number,
default: 1000,
required: false
- isRemUnit
singleHeight and singleWidth 是否开启 rem 度量
type: Boolean
default: true
required: false
- delay
Animation delay time
type: Number,
default: 0,
required: false
- ease
Animation effect, you can pass in Bezier curve value
type: String | cubic-bezier,
default: “ease-in”,
required: false
- copyNum
The number of times to copy the list, the default copy is once. When the height of the parent is greater than twice the rendering height of the list, you can use this parameter to control the number of times to copy the list to achieve a seamless scrolling effect
type: Number
default: 1
required: false
- wheel
Whether to enable wheel scrolling when mouse hover is enabled, not enabled by default
type: boolean
default: false< a i=3> required: false
- singleLine
Enable single-line horizontal scrolling
type: boolean
default: false
required: false
use
1. Register components
- Global registration
// **main.js**
import {
createApp } from 'vue';
import App from './App.vue';
import vue3SeamlessScroll from "vue3-seamless-scroll";
const app = createApp(App);
app.use(vue3SeamlessScroll);
app.mount('#app');
- Single file registration
<script>
import {
defineComponent } from "vue";
import {
Vue3SeamlessScroll } from "vue3-seamless-scroll";
export default defineComponent({
components: {
Vue3SeamlessScroll
}
})
</script>
2. Use components
We need to scroll the table content here. Wrapping the table directly with components will cause the header of the table to roll away, so there is a small change in use
The table code needs to be Make another copy. The first code modifies the CSS code to hide the body part of the table. The second code is wrapped with components and hides the header part;
<template>
<div class="container">
<el-table class="top-table" :data="tableData" border style="width: 100%;">
<el-table-column prop="type" label="类型" width="120" />
<el-table-column prop="name" label="姓名" />
<el-table-column prop="content" label="内容" />
</el-table>
<vue3-seamless-scroll class="seamless" :list="tableData" :hover="true" :step="0.4" :wheel="true" :isWatch="true">
<el-table class="bottom-table" :data="tableData" border style="width: 100%;">
<el-table-column prop="type" label="类型" width="120" />
<el-table-column prop="name" label="姓名" />
<el-table-column prop="content" label="内容" />
</el-table>
</vue3-seamless-scroll>
</div>
</template>
<script lang="ts" setup>
import {
ref } from 'vue'
const tableData: any = ref([])
const getData = () => {
for (let i = 0; i < 6; i++) {
tableData.value.push({
type: `家常菜${
i + 1}`,
name: `洋茄子炒鸡蛋${
i + 1}`,
content: `多情键客无情键${
i + 1}`
})
}
}
getData()
</script>
<style scoped>
.container {
width: 500px;
height: 300px;
}
.seamless {
width: 100%;
height: 220px;
overflow: hidden;
}
:deep .top-table .el-table__body-wrapper {
display: none;
}
:deep .bottom-table .el-table__header-wrapper {
display: none;
width: 100%;
}
</style>
Do you think the effect is okay?But, there are still problems. In the above example, we only created 6 pieces of data, but in reality There are about 50 pieces of data on a single page of the form in our project. Let’s change it to 50 pieces of data and see the effect
This plug-in has already made some changes for its use in table content scrolling. Now we need to make more changes to achieve the effect we want. This cannot be used directly out of the box for our current needs. So here I am Let’s just give up on this plan and leave it to see how to achieve the results we want later when we have time. For now, we still focus on work efficiency. Of course, if anyone among you has researched it, please feel free to send me a private message. There is no reward but I just want to take a look.
Option II
The second option is to directly operate the scroll bar and set a timer to let it scroll by itself. This is a relatively simple basic function of the front end.
Ideas
We only need to declare a timer, obtain the scroll area after obtainingtable
datascrollHeight
, and modify it in the timer scrollTop
Implement automatic scrolling of the scroll bar
After finishing the code soon, let's take a look at the effect.
my code
<template>
<div class="container">
<el-table ref="tableRef" :data="tableData" border style="width: 100%;height: 100%;">
<el-table-column prop="type" label="类型" width="120" />
<el-table-column prop="name" label="姓名" />
<el-table-column prop="content" label="内容" />
</el-table>
</div>
</template>
<script setup>
import {
ref, onMounted, onUnmounted } from 'vue'
let timer = null;
let tableRef = ref(null);
const scroll = () => {
// 在执行新的计时器前将之前的计时器清除
if (timer) clearInterval(timer);
let status = true;
// 获取表格滚动区域的dom
const scrollDom = tableRef.value.$refs.bodyWrapper.getElementsByClassName("el-scrollbar__wrap")[0];
// 增加监听事件鼠标移入停止滚动
scrollDom.addEventListener('mouseover', () => {
status = false;
});
// 鼠标移出恢复滚动
scrollDom.addEventListener('mouseout', () => {
status = true;
});
// 设置每秒滚动一行
timer = setInterval(() => {
if (status) {
// 设置每次滚动的像素
scrollDom.scrollTop += 40;
// 当滚动到底部时修改scrollTop回到顶部
if ((scrollDom.scrollHeight - (scrollDom.clientHeight + scrollDom.scrollTop)) < 1 ) {
scrollDom.scrollTop = 0;
}
}
}, 1000);
}
const tableData = ref([])
const getData = () => {
for (let i = 0; i < 50; i++) {
tableData.value.push({
type: `家常菜${
i + 1}`,
name: `洋茄子炒鸡蛋${
i + 1}`,
content: `多情键客无情键${
i + 1}`
})
}
// 要在数据都加载渲染完成后去获取表格的滚动区域dom
setTimeout(() => {
scroll()}, 1000)
}
onMounted(() => {
getData()
})
onUnmounted(() => {
// 组件卸载记得清除计时器
if (timer) clearInterval(timer);
timer = null;
})
</script>
<style scoped>
.container {
width: 500px;
height: 310px;
}
</style>
ending
Finally, the finished code is encapsulated and called in various places to avoid redundant code. Okay, that’s it for Class B today.