How to achieve seamless scrolling of table content in vue3, I wrote a bunch of redundant code

background

Recently, we are developing a large-screen visualization project. In addition to variousecharts 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>

Please add image description

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

Please add image description

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
Insert image description here

After finishing the code soon, let's take a look at the effect.

Please add image description

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.

Guess you like

Origin blog.csdn.net/zw7518/article/details/129752664