vue組件實現(xiàn)列表自動無限循環(huán)的方法
更新時間:2023年11月14日 09:35:55 作者:The?ever?Boy
最近剛好有個功能需要實現(xiàn)列表的無限循環(huán)滾動,這篇文章主要給大家介紹了關(guān)于vue組件實現(xiàn)列表自動無限循環(huán)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
前述:
用過vue-seamless-scroll插件,手動滾動列表到底部出現(xiàn)了空白現(xiàn)象,某些表現(xiàn)不符合項目場景,故自己寫了一個自己用的組件,如果有人需要可以直接拿去用,如有不足請指教勿噴!
主要功能:
- 列表自動無限循環(huán)滾動
- 鼠標(biāo)移入停止?jié)L動,移出繼續(xù)滾動
- 待滾動內(nèi)容高度未鋪滿并超過容器高度時不滾動
- 支持滾動速度、單次滾動時間間隔、單次滾動高度,三個參數(shù)控制
- 可自己手動滾動列表
效果圖 :
組件代碼:
<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, }, //滾動作單步運(yùn)動時的單純運(yùn)動距離 singleHeight: { type: Number, default: 0, }, //單步運(yùn)動的時間間隔 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); } // 開啟動畫 if (this.canRun()) this.reqAnimationFrame(); // this.reqAnimationFrame(); // 手動滾動到底部時滾動條重置到最上邊,同時滾動盒子重置為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; // 開啟動畫條件:滾動盒子(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; //滾動盒子 let scrollBox = this.$refs.scrollBox; //滾動盒子下邊的第一個scroll-item-box, let scrollItemBox = this.$refs.scrollItemBox; //滾動速度 this.speed = this.speed > 1 ? 1 : this.speed < 0 ? 0.1 : this.speed; //取第一個scrollItemBox高度 let definedHeight = this.getComputedHeight(scrollItemBox); //持續(xù)滾動 this.y = this.y + this.speed; scrollBox.style.top = -this.y + "px"; //====添加滾動間隔控制====開始 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á)到指定距離繼續(xù)執(zhí)行動畫 this.controleHeight += this.speed; } } //====添加滾動間隔控制====結(jié)束 //當(dāng)滾動到第一個scroll-item-box高度時scrollBox重置為top:0,視覺上是無縫滾動 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外層加個容器
- 參數(shù)waitTIme和singleHeight同時存在,才能出現(xiàn)滾動動畫間隔執(zhí)行的效果
- 樣式用了sass,如果有問題可以去掉或者導(dǎo)入sass
總結(jié)
到此這篇關(guān)于vue組件實現(xiàn)列表自動無限循環(huán)的文章就介紹到這了,更多相關(guān)vue列表自動無限循環(huán)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue-以文件流-blob-的形式-下載-導(dǎo)出文件操作
這篇文章主要介紹了vue-以文件流-blob-的形式-下載-導(dǎo)出文件操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08在vue和element-ui的table中實現(xiàn)分頁復(fù)選功能
這篇文章主要介紹了在vue和element-ui的table中實現(xiàn)分頁復(fù)選功能,本文代碼結(jié)合圖文的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-12-12