稀土掘金技术社区 06月11日 09:47
一个vue3指令让el-table自动轮播
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文分享了如何为Vue3和Element-plus UI库开发一个自定义的列表轮播指令,以实现列表的自动滚动效果。该指令的核心在于通过操作el-scrollbar__wrap的scrollTop属性来实现滚动,并结合鼠标移入停止、移出继续滚动的逻辑。文章详细介绍了实现思路、关键代码,以及如何注册和使用这个指令。最后,作者还分享了未来将其发展成开源项目的计划,希望通过这个指令集为开发者提供更多便利。

💡 **功能实现核心:** 该指令通过定时器不断改变el-scrollbar__wrap元素的scrollTop值来实现列表的自动滚动。同时,通过判断el-scrollbar__view的高度是否大于el-scrollbar__wrap的高度来决定是否滚动。

🖱️ **鼠标交互控制:** 当鼠标移入列表时,滚动停止;鼠标移出时,滚动恢复。通过监听mouseover和mouseout事件,结合isScroll变量控制定时器的启停,以及记录当前滚动位置。

⚙️ **指令结构与用法:** 指令包含created、mounted、unmounted三个生命周期钩子函数。在mounted中初始化定时器,并获取el-scrollbar__wrap和el-scrollbar__view元素。unmounted中清除定时器,防止内存泄漏。使用时,通过v-tableAutoScroll指令绑定到el-table上,并可配置滚动延迟时间。

🛠️ **代码关键细节:** 代码中定义了ElType接口,用于扩展HTMLElement,定义了timer、isScroll、curTableTopValue三个变量。其中curTableTopValue用于存储当前滚动位置,保证鼠标移出后,滚动可以从当前位置继续。

🚀 **未来展望:** 作者计划将该指令与其他实用指令打包成一个开源项目,为Vue3开发者提供一个指令集,简化开发流程。

原创 飞天猫猫头 2025-06-11 08:30 重庆

点击关注公众号,技术干货及时达!

关注更多AI编程资讯请去AI Coding专区:https://juejin.cn/aicoding

前言

本文开发的工具,是vue3 element-plus ui库专用的,需要对vue3指令概念有一定的了解

最近开发的项目中,需要对项目中大量的列表实现轮播效果,经过一番折腾.最终决定不使用第三方插件,手搓一个滚动指令.

效果展示

实现思路

第一步先确定功能

    列表自动滚动

    鼠标移入停止滚动

    鼠标移出继续滚动

    滚轮滚动完成,还可以继续在当前位置滚动

    元素少于一定条数时,不滚动

「滚动思路」

通过观察

el-table

的结构可以发现

el-scrollbar__view

里面放着所有的元素,而

el-scrollbar__wrap

是一个固定高度的容器,那么只需要获取到

el-scrollbar__wrap

这个DOM,并且再给一个定时器,不断的改变它的

scrollTop

值,就可以实现自动滚动的效果,这个值必须要用一个变量来存储,不然会失效

停止和继续滚动思路

设置一个

boolean

类型变量,每次执行定时器的时候判断一下,

true

就滚动,否则就不滚动

滚轮事件思路

为了每次鼠标在列表中滚动之后,我们的轮播还可以在当前滚动的位置,继续轮播,只需要在鼠标移出的时候,将当前

el-scrollbar__wrap

scrollTop

赋给前面存储的变量,这样执行定时器的时候,就可以继续在当前位置滚动

不滚动的思路

只需要判断

el-scrollbar__view

这个容器的高度,是否大于

el-scrollbar__wrap

的高度,是就可以滚动,不是就不滚动。

大致的思路是这样的,下面上源码

实现代码

文件名:tableAutoScroll.ts

interface ElType extends HTMLElement {  timer: number | null  isScroll: boolean  curTableTopValue: number}exportdefault {  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'    )[0as HTMLElement    const viewDom = el.getElementsByClassName(      'el-scrollbar__view'    )[0as 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)    }    el.timer = null    const tableDom = el.getElementsByClassName(      'el-scrollbar__wrap'    )[0as HTMLElement    tableDom.removeEventListener('mouseover'() => (el.isScroll = false))    tableDom.removeEventListener('mouseout'() => {      el.curTableTopValue = tableDom.scrollTop      el.isScroll = true    })  },}

上面代码中,我在 「created」中初始化了三个变量,分别用于存储,定时器对象 、是否滚动判断、滚动当前位置。

在 「mounted」中我还获取了一个「options」,主要是为了可以定制滚动速度

「用法」

    将这段代码放在你的文件夹中

    main.ts

    中注册这个指令

    import tableAutoScroll from './modules/tableAutoScroll.ts'const directives: any = {  tableAutoScroll,}/** * @function 批量注册指令 * @param app vue 实例对象 */export const install = (app: any) => {  Object.keys(directives).forEach((key) => {    app.directive(key, directives[key]) // 将每个directive注册到app中  })}

我这边是将自己的弄了一个批量注册,正常使用就像官网里面注册指令就可以了

在需要滚动的

el-table

上使用这个指令就可以

<!-- element 列表滚动指令插件 --><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:多少毫秒滚动一次 -->    <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), (item, index) => ({    date: '时间' + index,    name: '名称' + index,    address: '地点' + index,  }))  console.log('👉 ~ tableData.value=Array.from ~ tableData:', tableData)})</script><style lang="scss" scoped>.container {  height: 100%;  display: flex;  align-items: flex-start;  justify-content: center;  gap: 100px;  .el-table {    width: 500px;  }}</style>

上面这个例子,分别演示两种调用方法,带参数和不带参数

最后

做了这个工具之后,突然有很多思路,打算后面再做几个,做成一个开源项目,一个开源的vue3指令集

(创作者训练营强势上线,速戳上图了解)

""~

阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Vue3 Element-plus 指令 列表轮播
相关文章