vue3實(shí)現(xiàn)無(wú)縫滾動(dòng)組件的示例代碼
前言
在日常開(kāi)發(fā)中,經(jīng)常遇到需要支持列表循環(huán)滾動(dòng)展示,特別是在數(shù)據(jù)化大屏開(kāi)發(fā)中,無(wú)縫滾動(dòng)使用頻率更為頻繁,在jquery時(shí)代,我們常用的無(wú)縫滾動(dòng)組件為liMarquee,在vue中已經(jīng)有vue-seamless-scroll組件(通過(guò)Vue2實(shí)現(xiàn),不支持鼠標(biāo)手動(dòng)滾動(dòng)),但是在使用過(guò)程中,發(fā)現(xiàn)滾動(dòng)后會(huì)存在點(diǎn)擊事件失效的問(wèn)題,并且產(chǎn)品提了個(gè)需求,需要支持鼠標(biāo)手動(dòng)滾動(dòng),也要支持自動(dòng)滾動(dòng),于是痛定思痛,決定通過(guò)Vue3來(lái)實(shí)現(xiàn)該功能,該組件已經(jīng)實(shí)現(xiàn)上傳npm,可以直接安裝使用,鏈接在文尾。
實(shí)現(xiàn)
html部分
首先寫(xiě)一個(gè)基礎(chǔ)的list結(jié)構(gòu),通過(guò)插槽接收外部傳入的list數(shù)據(jù),因?yàn)樾枰獙?shí)現(xiàn)無(wú)縫滾動(dòng),需要復(fù)制出同一份的Dom,在最外層監(jiān)聽(tīng)鼠標(biāo)hover和leave的狀態(tài),以實(shí)現(xiàn)鼠標(biāo)hover暫停滾動(dòng),綁定鼠標(biāo)滾動(dòng)事件,在鼠標(biāo)滾動(dòng)時(shí)記住滾動(dòng)的位置,在恢復(fù)自動(dòng)滾動(dòng)時(shí)能從當(dāng)前滾動(dòng)位置繼續(xù)滾動(dòng)。
<div class="custom-list" ref="scrollBody" @mouseenter="mouseenterFunc" @mouseleave="mouseleaveFunc"
@mousewheel="mousewheelFunc">
<div class="list-body" :class="{
'list-body2': isHorizontal
}" ref="listBody" :style="{ transform: getScrollDistance() }">
<slot></slot>
</div>
<div class="list-body" :class="{
'list-body2': isHorizontal
}" ref="tBody" v-if="isCanScroll" :style="{ transform: getScrollDistance() }">
<slot></slot>
</div>
</div>實(shí)現(xiàn)邏輯
開(kāi)始
通過(guò)父級(jí)傳入的isHorizontal判斷是橫向滾動(dòng),還是垂直滾動(dòng)
const start = () => {
//判斷是否可以滾動(dòng)函數(shù)
let isScrollFunc = (bodySize:number, listSize:number) => {
if (bodySize > listSize) {
scrollDistance.value = 0;
isCanScroll.value = !1;
}
};
isStop.value = !1;
//判斷是否可以滾動(dòng)
if (!isHorizontal.value) {
isScrollFunc(bodyHeight.value, listHeight.value);
} else {
isScrollFunc(bodyWidth.value, listWidth.value);
}
if (isCanScroll.value) {
run();
}
}開(kāi)始滾動(dòng)
計(jì)算目前滾動(dòng)的距離,并判斷需要滾動(dòng)的方向,計(jì)算下一步滾動(dòng)的距離。
const run = () => {
//清空動(dòng)畫(huà)
clearAnimation();
animationFrame.value = window.requestAnimationFrame(() => {
//滾動(dòng)主邏輯函數(shù)
let main = (listSize:number, bodySize:number) => {
let tempScrollDistance = Math.abs(scrollDistance.value);
if (scrollDistance.value < 0) {
let cc = 2 * listSize - bodySize;
if (tempScrollDistance > cc) {
scrollDistance.value = -(listSize - bodySize);
}
} else {
scrollDistance.value = -listSize;
}
};
//根據(jù)滾動(dòng)方向判斷使用高度或?qū)挾瓤刂菩Ч?
if (!isHorizontal.value) {
main(listHeight.value, bodyHeight.value);
} else {
main(listWidth.value, bodyWidth.value);
}
//判斷滾動(dòng)值
if (!isStop.value) {
if (
props.scrollDirection === "top" ||
props.scrollDirection === "left"
) {
scrollDistance.value -= props.steep;
} else if (
props.scrollDirection === "bottom" ||
props.scrollDirection === "right"
) {
scrollDistance.value += props.steep;
}
run();
}
});
}獲取滾動(dòng)樣式
通過(guò)translate實(shí)現(xiàn)列表平移,已實(shí)現(xiàn)平滑滾動(dòng)。
const getScrollDistance = () => {
let style;
if (!isHorizontal.value) {
style = "translate(0px, " + scrollDistance.value + "px)";
} else {
style = "translate(" + scrollDistance.value + "px,0px)";
}
return style;
}
const clearAnimation = () => {
if (animationFrame.value) {
cancelAnimationFrame(animationFrame.value);
animationFrame.value = null;
}
}鼠標(biāo)滾動(dòng)
鼠標(biāo)滾動(dòng)時(shí)實(shí)時(shí)計(jì)算滾動(dòng)的距離,可通過(guò)傳入的鼠標(biāo)滾動(dòng)速率來(lái)計(jì)算每次滾動(dòng)多少。
const mousewheelFunc = (e:any) => {
if (!isCanScroll.value || !props.isRoller) {
return false;
}
let dis = e.deltaY;
if (dis > 0) {
scrollDistance.value -= props.rollerScrollDistance;
} else {
scrollDistance.value += props.rollerScrollDistance;
}
run();
}使用
該組件已上傳npm倉(cāng)庫(kù),歡迎satrt使用
npm install @fcli/vue-auto-scroll --save-dev 來(lái)安裝
在項(xiàng)目中使用
import VueAutoScroll from '@fcli/vue-auto-scroll';
const app=createApp(App)
app.use(VueAutoScroll);
使用示例:
<div class="content">
<vue-auto-scroll :data="list" :steep="0.5" scrollDirection="top" :isRoller="true" :rollerScrollDistance="50">
<div class="li" v-for="i in list" :key="i">
{{ i }}
</div>
</vue-auto-scroll>
</div>| 屬性 | 屬性名稱(chēng) | 類(lèi)型 | 可選值 |
|---|---|---|---|
| steep | 滾動(dòng)的速率 | number | 為正數(shù)即可 |
| scrollDirection | 滾動(dòng)的方向 | string | top ,bottom,left,right |
| isRoller | 是否可以使用滾輪滾動(dòng) | boolean | true,false |
| rollerScrollDistance | 滾輪滾動(dòng)的速率 | number | (isRoller 必須為 true)為正數(shù)即可 |
| data | 接收異步數(shù)據(jù) | array | 同步任務(wù)可不傳 |
注: 當(dāng)scrollDirection 為top或bottom時(shí),一定要為 vue-auto-scroll 組件設(shè)置高度。 當(dāng)scrollDirection 為left或right時(shí),一定要為 vue-auto-scroll 組件設(shè)置寬度。并為嵌入vue-auto-scroll中的標(biāo)簽設(shè)置樣式為display:inline-block; 示例樣式名為list-item可以更改為其他類(lèi)名。當(dāng)scrollDirection 為left或right時(shí),是基于行內(nèi)元素的“white-space: nowrap;” 來(lái)控制強(qiáng)制不換行的。有可能會(huì)影響其內(nèi)部的文字排列??梢栽趌ist-item 層添加 white-space: normal; 來(lái)處理給問(wèn)題。并為其添加固定寬度,以保證文字可以正常換行及插件的正確計(jì)算與顯示。如果沒(méi)有為其添加固定寬度,會(huì)造成插件獲取父容器層的寬度值錯(cuò)誤,導(dǎo)致顯示混亂

git地址:gitee.com/fcli/vue-auto-scroll
到此這篇關(guān)于vue3實(shí)現(xiàn)無(wú)縫滾動(dòng)組件的示例代碼的文章就介紹到這了,更多相關(guān)vue3無(wú)縫滾動(dòng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue條件渲染列表渲染原理示例詳解
- antd vue表格可編輯單元格以及求和實(shí)現(xiàn)方式
- vue實(shí)現(xiàn)無(wú)縫滾動(dòng)的示例詳解
- vue實(shí)現(xiàn)無(wú)縫滾動(dòng)手摸手教程
- vue實(shí)現(xiàn)消息向上無(wú)縫滾動(dòng)效果
- vue實(shí)現(xiàn)無(wú)限消息無(wú)縫滾動(dòng)
- vue實(shí)現(xiàn)簡(jiǎn)單無(wú)縫滾動(dòng)效果
- vue實(shí)現(xiàn)列表無(wú)縫滾動(dòng)效果
- vue實(shí)現(xiàn)列表垂直無(wú)縫滾動(dòng)
- vue實(shí)現(xiàn)列表無(wú)縫滾動(dòng)
- el-table動(dòng)態(tài)渲染列、可編輯單元格、虛擬無(wú)縫滾動(dòng)的實(shí)現(xiàn)
相關(guān)文章
基于 Vue 實(shí)現(xiàn)一個(gè)酷炫的 menu插件
本文給大家介紹基于 Vue 實(shí)現(xiàn)一個(gè)酷炫的 menu插件,此篇教程需要大家具備一定的css和vue基礎(chǔ)知識(shí),本文分步驟給大家介紹的非常詳細(xì),需要的朋友參考下吧2017-11-11
vue使用element-ui tabs切換echarts解決寬度100%方式
這篇文章主要介紹了vue使用element-ui tabs切換echarts解決寬度100%方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
Vue.js常用指令之循環(huán)使用v-for指令教程
這篇文章主要跟大家介紹了關(guān)于Vue.js常用指令之循環(huán)使用v-for指令的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-06-06
淺談vue 組件中的setInterval方法和window的不同
這篇文章主要介紹了淺談vue 組件中的setInterval方法和window的不同,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07
vue+vuex+axios從后臺(tái)獲取數(shù)據(jù)存入vuex,組件之間共享數(shù)據(jù)操作
這篇文章主要介紹了vue+vuex+axios從后臺(tái)獲取數(shù)據(jù)存入vuex,組件之間共享數(shù)據(jù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07
vue + gojs 實(shí)現(xiàn)拖拽流程圖效果
最近一段時(shí)間在研究go.js,它是一款前端開(kāi)發(fā)畫(huà)流程圖的一個(gè)插件,也是一個(gè)難點(diǎn),要說(shuō)為什么是難點(diǎn),首先,它是依賴(lài)畫(huà)布canvas知識(shí)開(kāi)發(fā),這篇文章主要介紹了vue + gojs 實(shí)現(xiàn)拖拽流程圖,需要的朋友可以參考下2023-03-03
Vue如何實(shí)現(xiàn)分批加載數(shù)據(jù)
這篇文章主要介紹了Vue如何實(shí)現(xiàn)分批加載數(shù)據(jù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04
解決vue多個(gè)路由共用一個(gè)頁(yè)面的問(wèn)題
下面小編就為大家分享一篇解決vue多個(gè)路由共用一個(gè)頁(yè)面的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03

