背景:接上一篇,大屏中大多时候会遇到无缝滚动的需求,接下来就来看看如何实现吧
直接贴代码
<template>
<div>
<div class="title">今日实时问题治理</div>
<div @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave" class="main_container">
<div ref="scrollContainer" class="scroll_container">
<div v-for="item in listData" :key="item.id" class="scroll_item">
<span>{{ item.time }}</span>
<span>{{ item.name }}</span>
<span>{{ item.type }}</span>
<span>{{ item.desc }}</span>
<div :class="item.status === 1 ? 'low' : 'high'">{{ item.status === 1 ? '低风险' : '一般风险' }}</div>
<span>{{ item.state }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import {reactive, ref, onMounted, onBeforeUnmount, onUnmounted, nextTick} from 'vue'
let timer = ref(null)
let scrollContainer = ref(null)
let listData = reactive([
{
time: '14:50',
name: '车间1',
type: '作业活动',
desc: '保险装置未过关',
status: 2,
state: '已完成'
},
{
time: '14:50',
name: '车间1',
type: '作业活动',
desc: '保险装置未过关',
status: 1,
state: '已完成'
},
{
time: '14:50',
name: '车间1',
type: '作业活动',
desc: '保险装置未过关',
status: 2,
state: '已完成'
},
{
time: '14:50',
name: '车间1',
type: '作业活动',
desc: '保险装置未过关',
status: 2,
state: '已完成'
},
{
time: '14:50',
name: '车间1',
type: '作业活动',
desc: '保险装置未过关',
status: 1,
state: '已完成'
},
{
time: '14:50',
name: '车间1',
type: '作业活动',
desc: '保险装置未过关',
status: 2,
state: '已完成'
},
])
start()
onBeforeUnmount(()=>{
clearTimeout(timer.value)
})
onUnmounted(()=>{
clearTimeout(timer.value)
})
function handleMouseEnter() {
clearTimeout(timer.value)
}
function handleMouseLeave() {
start()
}
// 开启定时器
function start() {
clearTimeout(timer.value)
// 定时器触发周期
let speed = ref(25)
timer.value = setInterval(ListScroll, speed.value)
}
function ListScroll() {
let scrollDom = scrollContainer.value
// 判读组件是否渲染完成
if(scrollDom.offsetHeight == 0) {
scrollDom = scrollContainer.value
}else {
// 如果列表数量过少不进行滚动
if(scrollDom.children.length < 4) {
clearTimeout(timer.value)
return
}
// 组件进行滚动
scrollDom.scrollTop += 1
// 判断是否滚动到底部
if(scrollDom.scrollTop == (scrollDom.scrollHeight - scrollDom.clientHeight)) {
// 获取组件第一个节点
let first = scrollDom.children[0]
// 删除节点
scrollDom.removeChild(first)
// 将该节点拼接到组件最后
scrollDom.append(first)
}
}
}
</script>
<style lang="less" scoped>
.title {
color: #fff;
text-align: center;
background-color: rgba(18, 51, 95, 0.9);
font-size: 16px;
padding: 8px 0;
font-weight: 700;
}
.main_container {
height: 300px;
padding: 20px;
.scroll_container {
color: #fff;
width: 100%;
height: 100%;
overflow: hidden;
.scroll_item {
padding: 0 16px;
display: flex;
align-items: center;
justify-content: space-between;
height: 48px;
margin-bottom: 10px;
div {
width: 72px;
text-align: center;
color: #ffffff;
border-radius: 4px;
margin-right: 8px;
height: 30px;
line-height: 30px;
}
.low {
background: #3471ff;
}
.high {
background: #ffca19;
}
}
.scroll_item:nth-child(odd) {
background-color: rgba(255, 255, 255, 0.3);
color: white;
}
}
}
</style>