vue3大屏实现列表无缝滚动

背景:接上一篇,大屏中大多时候会遇到无缝滚动的需求,接下来就来看看如何实现吧

直接贴代码
<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>

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值