您好,登錄后才能下訂單哦!
先上效果圖:
(1) 看起來可能有點(diǎn)卡頓,但是實(shí)際上頁(yè)面上看起來挺順暢的。
(2) 思路就是獲取每一個(gè)列表的寬度,設(shè)置定時(shí)器移動(dòng)列表,當(dāng)移動(dòng)的距離達(dá)到一個(gè)列表的寬度的時(shí)候,把這個(gè)距離放到數(shù)組的最后。這樣就能達(dá)成無縫循環(huán)滾動(dòng)了。
大致的情況就是下面這樣:
接下來就是代碼的實(shí)現(xiàn):
index.vue 引入組件
<template> <div> <marqueeLeft :send-val='send'></marqueeLeft > </div> </template> <script> import marqueeLeft from '../components/marquee' export default { data:function(){ return{ send:[{place: "來自東莞市的", name: "黃女士"}, {place: "來自太原市的", name: "吳先生"}, {place: "來自常州市的", name: "戚先生"}, {place: "來自金華市的", name: "尤先生"}, {place: "來自貴陽(yáng)市的", name: "陳女士"}, {place: "來自長(zhǎng)春市的", name: "魏女士"}, {place: "來自泉州市的", name: "褚先生"}, {place: "來自南昌市的", name: "蔣女士"}, {place: "來自南京市的", name: "沈先生"}, {place: "來自天津市的", name: "韓先生"}, {place: "來自寧波市的", name: "鄒女士"}, {place: "來自嘉興市的", name: "周女士"}, {place: "來自長(zhǎng)沙市的", name: "秦先生"}, {place: "來自濟(jì)南市的", name: "孫女士"}, {place: "來自杭州市的", name: "楊先生"}] } }, components:{ marqueeLeft }, } </script>
marquee.vue 組件頁(yè)面
<template> <div class="my-outbox"> <div class="my-inbox" ref='box'> <div class="my-list" v-for="(item,index) in sendVal" :key='index' ref='list'> {{item.place}}<span class="my-uname">{{item.name}}</span>剛剛購(gòu)買了產(chǎn)品 </div> </div> </div> </template> <script> export default { name:'my-marquee-left', props:{ sendVal:Array }, data() { return { nowTime:null,//定時(shí)器標(biāo)識(shí) disArr:[],//每一個(gè)內(nèi)容的寬度 } }, mounted:function(){ var that = this; var item = this.$refs.list; var len = this.sendVal.length; var arr = []; var margin = this.getMargin(item[0]) //因?yàn)樵O(shè)置的margin值一樣,所以取第一個(gè)就行。 for(var i = 0;i < len;i++){ arr.push(item[i].clientWidth + margin)//把寬度和 margin 加起來就是每一個(gè)元素需要移動(dòng)的距離 } this.disArr = arr; this.moveLeft(); }, beforeDestroy:function(){ clearInterval(this.nowTime);//頁(yè)面關(guān)閉清除定時(shí)器 this.nowTime = null;//清除定時(shí)器標(biāo)識(shí) }, methods:{ //獲取margin屬性 getMargin:function(obj){ var marg = window.getComputedStyle(obj,null)['margin-right']; marg = marg.replace('px','') return Number(marg) //強(qiáng)制轉(zhuǎn)化成數(shù)字 }, //移動(dòng)的方法 moveLeft:function(){ var outbox = this.$refs.box; var that=this; var startDis = 0;//初始位置 this.nowTime = setInterval(function(){ startDis -= 0.5; if(Math.abs(startDis) > Math.abs(that.disArr[0])){ that.disArr.push(that.disArr.shift())//每次移動(dòng)完一個(gè)元素的距離,就把這個(gè)元素的寬度 that.sendVal.push(that.sendVal.shift())//每次移動(dòng)完一個(gè)元素的距離,就把列表數(shù)據(jù)的第一項(xiàng)放到最后一項(xiàng) startDis = 0; } outbox.style = 'transform: translateX('+ startDis +'px)'; //每次都讓盒子移動(dòng)指定的距離 },1000/60) } } } </script> <style lang="less" scoped> .my-outbox{ color: #D7BC8D; overflow: hidden; height: 35px; background: #422b02; .my-inbox{ white-space: nowrap; .my-list{ margin-right: 25px; display: inline-block; font-size: 13px; height: 35px; line-height: 35px; .my-uname{ color: #FF8900; } } } } </style>
(1) 添加一個(gè)獲取margin的方法,是為了保證如果是使用 rem em 等單位時(shí),margin值不會(huì)出現(xiàn)偏差的情況
(2) 如果引入組件的頁(yè)面中,send-val的值是異步請(qǐng)求的。那么,在marquee.vue組件頁(yè)面,多數(shù)情況會(huì)獲取不了 refs 。這時(shí)候我自己的解決方法是:
<marqueeLeft :send-val='send' v-if='send'></marqueeLeft >
表示只有當(dāng) send 不為空的時(shí)候才渲染該組件,不過這種情況會(huì)導(dǎo)致如果 請(qǐng)求響應(yīng)太慢,組件會(huì)一直渲染不出來,就可能會(huì)影響布局。
(3) 如果不想每次都去設(shè)置transform,那么可以把transform放到該元素上,然后修改data中的數(shù)據(jù)就行了,比如:
<div class="my-inbox" :style='transform: translateX('+ cssStyle +'px)'></div>
// 然后在 js 中把 每次移動(dòng)的值,賦值給cssStyle就行了。不過我感覺這種沒什么區(qū)別
如果想實(shí)現(xiàn),上下無縫滾動(dòng),這種效果。思路和左右無縫滾動(dòng)一樣,基本上只需要把 transform 改成 Y軸移動(dòng) ,每個(gè)列表的寬度改成高度就行了。
不清楚這種方式實(shí)現(xiàn)是否會(huì)有什么問題,F(xiàn)PS一直保持在 接近60左右。暫時(shí)沒發(fā)現(xiàn)什么缺點(diǎn)。。。
以上所述是小編給大家介紹的vue自定義marquee無縫滾動(dòng)組件詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)億速云網(wǎng)站的支持!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。