详解vue⾃定义marquee⽆缝滚动组件
先上效果图:
(1)看起来可能有点卡顿,但是实际上页⾯上看起来挺顺畅的。
(2)思路就是获取每⼀个列表的宽度,设置定时器移动列表,当移动的距离达到⼀个列表的宽度的时候,把这个距离放到数组的最后。这样就能达成⽆缝循环滚动了。
⼤致的情况就是下⾯这样:
接下来就是代码的实现:
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: "来⾃贵阳市的", name: "陈⼥⼠"},
{place: "来⾃长春市的", name: "魏⼥⼠"},
{place: "来⾃泉州市的", name: "褚先⽣"},
{place: "来⾃南昌市的", name: "蒋⼥⼠"},
{place: "来⾃南京市的", name: "沈先⽣"},
{place: "来⾃天津市的", name: "韩先⽣"},
{place: "来⾃宁波市的", name: "邹⼥⼠"},
{place: "来⾃嘉兴市的", name: "周⼥⼠"},
{place: "来⾃长沙市的", name: "秦先⽣"},
{place: "来⾃济南市的", name: "孙⼥⼠"},
{place: "来⾃杭州市的", name: "杨先⽣"}]
}
},
components:{ marqueeLeft },
}
</script>
marquee.vue 组件页⾯
<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>刚刚购买了产品
</div>
</div>
</div>
</template>
<script>
marquee marqueeexport default {
name:'my-marquee-left',
props:{
sendVal:Array
},
data() {
return {
nowTime:null,//定时器标识
disArr:[],//每⼀个内容的宽度
}
},
mounted:function(){
var that = this;
var item = this.$refs.list;
var len = this.sendVal.length;
var arr = [];
var margin = Margin(item[0]) //因为设置的margin值⼀样,所以取第⼀个就⾏。
for(var i = 0;i < len;i++){
arr.push(item[i].clientWidth + margin)//把宽度和 margin 加起来就是每⼀个元素需要移动的距离
}
this.disArr = arr;
},
beforeDestroy:function(){
wTime);//页⾯关闭清除定时器
},
methods:{
//获取margin属性
getMargin:function(obj){
var marg = ComputedStyle(obj,null)['margin-right'];
marg = place('px','')
return Number(marg) //强制转化成数字
},
//移动的⽅法
moveLeft:function(){
var outbox = this.$refs.box;
var that=this;
var startDis = 0;//初始位置
startDis -= 0.5;
if(Math.abs(startDis) > Math.abs(that.disArr[0])){
that.disArr.push(that.disArr.shift())//每次移动完⼀个元素的距离,就把这个元素的宽度
that.sendVal.push(that.sendVal.shift())//每次移动完⼀个元素的距离,就把列表数据的第⼀项放到最后⼀项
startDis = 0;
}
outbox.style = 'transform: translateX('+ startDis +'px)'; //每次都让盒⼦移动指定的距离
},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)添加⼀个获取margin的⽅法,是为了保证如果是使⽤ rem em 等单位时,margin值不会出现偏差的情况
(2)如果引⼊组件的页⾯中,send-val的值是异步请求的。那么,在marquee.vue组件页⾯,多数情况会获取不了 refs 。这时候我⾃⼰的解决⽅法是:
<marqueeLeft :send-val='send' v-if='send'></marqueeLeft >
表⽰只有当 send 不为空的时候才渲染该组件,不过这种情况会导致如果请求响应太慢,组件会⼀直渲染不出来,就可能会影响布局。
(3)如果不想每次都去设置transform,那么可以把transform放到该元素上,然后修改data中的数据就⾏了,⽐如:
<div class="my-inbox" :style='transform: translateX('+ cssStyle +'px)'></div>
// 然后在 js 中把每次移动的值,赋值给cssStyle就⾏了。不过我感觉这种没什么区别
如果想实现,上下⽆缝滚动,这种效果。思路和左右⽆缝滚动⼀样,基本上只需要把 transform 改成 Y轴移动,每个列表的宽度改成⾼度就⾏了。
不清楚这种⽅式实现是否会有什么问题,FPS⼀直保持在接近60左右。暂时没发现什么缺点。。。
以上所述是⼩编给⼤家介绍的vue⾃定义marquee⽆缝滚动组件详解整合,希望对⼤家有所帮助,如果⼤家有任何疑问请给我留⾔,⼩编会及时回复⼤家的。在此也⾮常感谢⼤家对⽹站的⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论