vue組件實(shí)現(xiàn)列表自動(dòng)無限循環(huán)的方法
前述:
用過vue-seamless-scroll插件,手動(dòng)滾動(dòng)列表到底部出現(xiàn)了空白現(xiàn)象,某些表現(xiàn)不符合項(xiàng)目場景,故自己寫了一個(gè)自己用的組件,如果有人需要可以直接拿去用,如有不足請指教勿噴!
主要功能:
- 列表自動(dòng)無限循環(huán)滾動(dòng)
- 鼠標(biāo)移入停止?jié)L動(dòng),移出繼續(xù)滾動(dòng)
- 待滾動(dòng)內(nèi)容高度未鋪滿并超過容器高度時(shí)不滾動(dòng)
- 支持滾動(dòng)速度、單次滾動(dòng)時(shí)間間隔、單次滾動(dòng)高度,三個(gè)參數(shù)控制
- 可自己手動(dòng)滾動(dòng)列表
效果圖 :

組件代碼:
<template>
<div class="scroll-outer" ref="outer" @mouseover="onMouseover" @mouseleave="onMouseleave">
<div class="scroll-inner-box" ref="scrollBox">
<div class="scroll-item-box" ref="scrollItemBox">
<slot></slot>
</div>
<div v-if="showSecond" class="scroll-item-box">
<slot></slot>
</div>
</div>
</div>
</template>
<script>
export default {
name: "my-auto-scroll",
props: {
list: {
type: Array,
default: () => [
{ name: "張三1" },
{ name: "張三2" },
{ name: "張三3" },
{ name: "張三4" },
{ name: "張三5" },
{ name: "張三6" },
{ name: "張三7" },
{ name: "張三8" },
{ name: "張三9" },
{ name: "張三10" },
],
},
speed: {
type: Number,
default: 0.1,
},
//滾動(dòng)作單步運(yùn)動(dòng)時(shí)的單純運(yùn)動(dòng)距離
singleHeight: {
type: Number,
default: 0,
},
//單步運(yùn)動(dòng)的時(shí)間間隔
waitTime: {
type: Number,
default: 0,
},
},
data() {
return {
rafId: null,
y: 0,
showSecond: false,
controleHeight: 0,
};
},
watch: {
list: {
handler(newVal) {
var that = this;
this.$nextTick(() => {
console.log(newVal);
if (newVal && newVal.length > 0) {
let scrollBox = that.$refs.scrollBox;
let outer = that.$refs.outer;
if (this.myReq) {
cancelAnimationFrame(this.myReq);
}
// 開啟動(dòng)畫
if (this.canRun()) this.reqAnimationFrame();
// this.reqAnimationFrame();
// 手動(dòng)滾動(dòng)到底部時(shí)滾動(dòng)條重置到最上邊,同時(shí)滾動(dòng)盒子重置為top:0
outer.addEventListener("scroll", function () {
if (
outer.scrollTop + outer.clientHeight + 4 >=
outer.scrollHeight
) {
outer.scrollTop = 0;
that.y = 0;
scrollBox.style.top = 0;
}
});
}
});
},
deep: true,
immediate: true,
},
},
mounted() {
window.addEventListener("resize", this.listenResizeFn);
},
methods: {
listenResizeFn() {
cancelAnimationFrame(this.myReq);
if (this.canRun()) this.reqAnimationFrame();
},
onMouseover() {
clearTimeout(this.timer);
cancelAnimationFrame(this.myReq);
},
onMouseleave() {
if (this.canRun()) this.reqAnimationFrame();
},
canRun() {
let scrollItemBox = this.$refs.scrollItemBox;
let scrollBox = this.$refs.scrollBox;
let outer = this.$refs.outer;
// 開啟動(dòng)畫條件:滾動(dòng)盒子(scrollBox)高度高于外層容器(outer)高度
if (outer.offsetHeight >= scrollItemBox.offsetHeight) {
this.showSecond = false;
outer.scrollTop = 0;
this.y = 0;
scrollBox.style.top = 0;
return false;
} else {
this.showSecond = true;
return true;
}
},
//獲取dom元素的高度:content+padding+margin+border
getComputedHeight(dom) {
let computedStyle = getComputedStyle(dom);
let computedHeight =
dom.offsetHeight +
parseFloat(computedStyle.marginTop) +
parseFloat(computedStyle.marginBottom);
return computedHeight;
},
reqAnimationFrame() {
//外層容器
let outer = this.$refs.outer;
//滾動(dòng)盒子
let scrollBox = this.$refs.scrollBox;
//滾動(dòng)盒子下邊的第一個(gè)scroll-item-box,
let scrollItemBox = this.$refs.scrollItemBox;
//滾動(dòng)速度
this.speed = this.speed > 1 ? 1 : this.speed < 0 ? 0.1 : this.speed;
//取第一個(gè)scrollItemBox高度
let definedHeight = this.getComputedHeight(scrollItemBox);
//持續(xù)滾動(dòng)
this.y = this.y + this.speed;
scrollBox.style.top = -this.y + "px";
//====添加滾動(dòng)間隔控制====開始
if (this.singleHeight >= 20 && this.waitTime > 500) {
if (this.controleHeight >= this.singleHeight) {
cancelAnimationFrame(this.myReq);
this.controleHeight = 0;
this.timer = setTimeout(() => {
if (this.canRun) this.reqAnimationFrame();
}, this.waitTime);
return;
} else {
// 一次移動(dòng)高度未達(dá)到指定距離繼續(xù)執(zhí)行動(dòng)畫
this.controleHeight += this.speed;
}
}
//====添加滾動(dòng)間隔控制====結(jié)束
//當(dāng)滾動(dòng)到第一個(gè)scroll-item-box高度時(shí)scrollBox重置為top:0,視覺上是無縫滾動(dòng)
if (this.y >= definedHeight) {
this.y = 0;
}
this.myReq = window.requestAnimationFrame(this.reqAnimationFrame);
},
},
destroyed() {
window.removeEventListener("resize", this.listenResizeFn);
cancelAnimationFrame(this.myReq);
if (this.timer) clearTimeout(this.timer);
},
};
</script>
<style lang="scss">
.scroll-outer {
height: 100%;
overflow-x: hidden;
position: relative;
&::-webkit-scrollbar {
width: 0.3vw;
}
&:hover::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 0.1vw rgba(0, 0, 0, 0.3);
border-radius: 0.1vw;
background-color: #295099;
opacity: 1;
// display: none;
}
&:hover::-webkit-scrollbar-thumb {
opacity: 1;
border-radius: 0.1vw;
-webkit-box-shadow: inset 0 0 0.1vw rgba(0, 0, 0, 0.3);
background-color: #0ba9ea;
}
}
.scroll-inner-box {
height: auto;
position: absolute;
width: 100%;
top: 0;
left: 0;
}
</style>
使用示例:
import autoScroll from "@/components/autoScroll";
<autoScroll :list="list" :speed="0.5" :waitTime="2000" :singleHeight="100">
<div class="t-item" v-for="(item,index) in list" :key="index">
<div class="tvalue" style="flex: 0 0 30%;">{{ item.jgjc }}</div>
<span class="tvalue">{{ item.total||'--' }}</span>
<span class="tvalue" style="color:#0FCBDE">{{ item.ypc||'--' }}</span>
<span class="tvalue" style="color:#F15730">{{ item.zlz||'--' }}</span>
<span class="tvalue" style="color:#17DB68">{{ item.zlwc||'--' }}</span>
</div>
</autoScroll>使用注意:
- autoScroll容器默認(rèn)是占外層容器寬高百分百,要自己在autoScroll外層加個(gè)容器
- 參數(shù)waitTIme和singleHeight同時(shí)存在,才能出現(xiàn)滾動(dòng)動(dòng)畫間隔執(zhí)行的效果
- 樣式用了sass,如果有問題可以去掉或者導(dǎo)入sass
總結(jié)
到此這篇關(guān)于vue組件實(shí)現(xiàn)列表自動(dòng)無限循環(huán)的文章就介紹到這了,更多相關(guān)vue列表自動(dòng)無限循環(huán)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue基于echarts實(shí)現(xiàn)立體柱形圖
這篇文章主要為大家詳細(xì)介紹了vue基于echarts實(shí)現(xiàn)立體柱形圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
vue-以文件流-blob-的形式-下載-導(dǎo)出文件操作
這篇文章主要介紹了vue-以文件流-blob-的形式-下載-導(dǎo)出文件操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
在vue和element-ui的table中實(shí)現(xiàn)分頁復(fù)選功能
這篇文章主要介紹了在vue和element-ui的table中實(shí)現(xiàn)分頁復(fù)選功能,本文代碼結(jié)合圖文的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
vue實(shí)現(xiàn)圖片滑動(dòng)驗(yàn)證功能
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)圖片滑動(dòng)驗(yàn)證功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09

