先看效果
html 部分
<ul
class="flex center-box"
:style="{
'--time':animationTime, // 动画播放时间,需要动态计算 传入
animationPlayState: targetList.length < 4 ? 'paused' : '', // 我这里一行最多展示3个li标签 当要滚动的li长度小于4不需要动画
width:originLen*7.552+'vw' // ul的宽度是原始li标签(这里注意:为了实现无缝滚动后面会改变li的数量,这里取原始数量)的宽度 * 数量
}"
>
<li
class="item-box"
v-for="(item, index) in targetList"
:key="index"
>
<div class="title">这里是要滚动的子内容</div>
</li>
</ul>
js部分
容器ul的宽度为红色背景部分 后面非红色背景的是我们手动添加进去的3个li 这样就解决了无缝滚动的问题
data() {
return {
targetList: [],
originLen: 0,
animationTime:0, // 動畫時長
};
},
methods:{
getTargetProfile().then((res) => { // 从接口拿到要展示的数据
if (res.data) {
this.targetList = res.data.standardMonitoringVos; // 原始数据
this.originLen = this.targetList?.length || 0; // 原始长度
if (this.originLen > 3) { // 我当前容器一次展示3个li 所以判断如果大于3就要处理,小于3不滚动
this.targetList.push(...this.targetList.slice(0,3)) // 因为容器要始终展示3个li 所以在原始数据最后一个滚动完后要填充3个进去 避免出现空白
}
// 計算動畫時間
this.animationTime = this.targetList.length * 2 + 's' // 这里的长度计算要加上后面补充的3个li的数量
}
});
}
style
.flex {
display: flex;
gap: 0.729vw;
}
.center-box {
animation: marquee-horizontal var(--time) infinite linear; // scss中使用js变量 动态计算动画时间
}
.item-box {
width: 6.823vw;
box-sizing: border-box;
flex-shrink: 0;
font-size: 0.833vw;
padding: 0.521vw 0.625vw;
background: rgba(167, 209, 255, 0.15);
border-radius: 0.208vw;
overflow: hidden;
}
注意:
- 容器一次展示几个li,则需要在要展示的数据后再重复添加几个li
- 容器的宽度要动态计算
- 动画时长动态计算