注册
web

🌿一个vue3指令让el-table自动轮播

img


前言



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



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


效果展示


列表滚动.webp


实现思路


第一步先确定功能



  • 列表自动滚动
  • 鼠标移入停止滚动
  • 鼠标移出继续滚动
  • 滚轮滚动完成,还可以继续在当前位置滚动
  • 元素少于一定条数时,不滚动

滚动思路


image-20241226223121217.png


image-20241226223310536.png


通过观察el-table的结构可以发现el-scrollbar__view里面放着所有的元素,而el-scrollbar__wrap是一个固定高度的容器,那么只需要获取到el-scrollbar__wrap这个DOM,并且再给一个定时器,不断的改变它的scrollTop值,就可以实现自动滚动的效果,这个值必须要用一个变量来存储,不然会失效


停止和继续滚动思路


设置一个boolean类型变量,每次执行定时器的时候判断一下,true就滚动,否则就不滚动


滚轮事件思路


为了每次鼠标在列表中滚动之后,我们的轮播还可以在当前滚动的位置,继续轮播,只需要在鼠标移出的时候,将当前el-scrollbar__wrapscrollTop赋给前面存储的变量,这样执行定时器的时候,就可以继续在当前位置滚动


不滚动的思路


​ 只需要判断el-scrollbar__view这个容器的高度,是否大于el-scrollbar__wrap的高度,是就可以滚动,不是就不滚动。


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


实现代码


文件名:tableAutoScroll.ts


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)
}
el.timer = null

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
})
},
}

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


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


用法



  1. 将这段代码放在你的文件夹中
  2. 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中
    })
    }



image-20241226224940418.png
image-20241226225027524.png


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


在需要滚动的el-table上使用这个指令就可以


image-20241226225257264.png


<!-- 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指令集


作者:BAO_OA
来源:juejin.cn/post/7452667228006678540

0 个评论

要回复文章请先登录注册