Frontend Development 8 min read

How to Build a Custom Vue3 Auto‑Scrolling Table Directive with Element‑Plus

This article explains how to create a custom Vue 3 directive for automatic scrolling of Element‑Plus tables, covering the underlying logic, handling mouse events, conditional scrolling, and integration steps with code examples, enabling developers to implement smooth list carousels without third‑party plugins.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
How to Build a Custom Vue3 Auto‑Scrolling Table Directive with Element‑Plus

Introduction

This tool is a Vue3 directive designed for the Element‑Plus UI library; it assumes a basic understanding of Vue3 directives.

Demo

Demo GIF
Demo GIF

Implementation Idea

First determine the required features:

Automatic list scrolling

Pause on mouse hover

Resume on mouse leave

Continue scrolling from the current position after wheel scroll completes

Do not scroll when the number of items is below a certain threshold

Scrolling Logic

By inspecting the

el-table

structure, the

el-scrollbar__view

contains all items, while

el-scrollbar__wrap

is a fixed‑height container. The directive obtains the

el-scrollbar__wrap

element, sets a timer, and repeatedly updates its

scrollTop

value, storing the value in a variable to keep it persistent.

Pause/Resume Logic

A boolean variable is used inside the timer; when the variable is

true

the scroll proceeds, otherwise it stops.

Wheel Event Logic

When the mouse leaves the list, the current

scrollTop

of

el-scrollbar__wrap

is saved to the variable so the timer can continue scrolling from that position.

Non‑Scrolling Logic

The directive compares the height of

el-scrollbar__view

with the height of

el-scrollbar__wrap

; scrolling only occurs when the content height exceeds the container height.

Source Code

File:

tableAutoScroll.ts
<code>interface ElType extends HTMLElement {
  timer: number | null;
  isScroll: boolean;
  curTableTopValue: number;
}

export default {
  created(el: ElType) {
    el.timer = null;
    el.isScroll = true;
    el.curTableTopValue = 0;
  },
  mounted(el: ElType, binding: { value?: { delay?: number } }) {
    const { delay = 15 } = binding.value || {};
    const tableDom = el.getElementsByClassName('el-scrollbar__wrap')[0] as HTMLElement;
    const viewDom = el.getElementsByClassName('el-scrollbar__view')[0] as HTMLElement;

    const onMouseOver = () => (el.isScroll = false);
    const onMouseOut = () => {
      el.curTableTopValue = tableDom.scrollTop;
      el.isScroll = true;
    };

    tableDom.addEventListener('mouseover', onMouseOver);
    tableDom.addEventListener('mouseout', onMouseOut);

    el.timer = window.setInterval(() => {
      const viewDomClientHeight = viewDom.scrollHeight;
      const tableDomClientHeight = el.clientHeight;

      if (el.isScroll && viewDomClientHeight > tableDomClientHeight) {
        const curScrollPosition = tableDom.clientHeight + el.curTableTopValue;
        el.curTableTopValue =
          curScrollPosition === tableDom.scrollHeight ? 0 : el.curTableTopValue + 1;
        tableDom.scrollTop = el.curTableTopValue;
      }
    }, delay);
  },
  unmounted(el: ElType) {
    if (el.timer !== null) {
      clearInterval(el.timer);
    }
    const tableDom = el.getElementsByClassName('el-scrollbar__wrap')[0] as HTMLElement;
    tableDom.removeEventListener('mouseover', () => (el.isScroll = false));
    tableDom.removeEventListener('mouseout', () => {
      el.curTableTopValue = tableDom.scrollTop;
      el.isScroll = true;
    });
  },
};</code>

The

created

hook initializes three variables: a timer reference, a scroll‑enabled flag, and the current scroll position. The

mounted

hook reads an optional

delay

option to customize the scroll speed.

Usage

Place the directive file in your project.

Register the directive in

main.ts

and optionally expose an

install

function for batch registration.

<code>import tableAutoScroll from './modules/tableAutoScroll.ts';
const directives: any = { tableAutoScroll };
export const install = (app: any) => {
  Object.keys(directives).forEach(key => {
    app.directive(key, directives[key]);
  });
};</code>

Apply the directive to an

el-table

:

<code><!-- element list scroll directive plugin -->
<template>
  <div class="container">
    <el-table v-tableAutoScroll :data="tableData" height="300">
      <el-table-column prop="date" label="时间" />
      <el-table-column prop="name" label="名称" />
      <el-table-column prop="address" label="Address" />
    </el-table>

    <!-- delay: milliseconds per scroll -->
    <el-table
      v-tableAutoScroll="{ delay: 50 }"
      :data="tableData"
      height="300"
    >
      <el-table-column prop="date" label="时间" />
      <el-table-column prop="name" label="名称" />
      <el-table-column prop="address" label="Address" />
    </el-table>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
const tableData = ref<any>([]);
onMounted(() => {
  tableData.value = Array.from(Array(100), (_, index) => ({
    date: '时间' + index,
    name: '名称' + index,
    address: '地点' + index,
  }));
});
</script>

<style lang="scss" scoped>
.container {
  height: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 100px;
  .el-table {
    width: 500px;
  }
}
</style>
</code>

The example demonstrates both parameter‑less and parameterized usage.

Conclusion

After building this tool, the author plans to develop additional Vue3 directives and publish them as an open‑source directive collection.

frontendVue3Element-PlusDirectiveAuto-Scroll
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.