关于vue实现无缝滚动--数据大屏可能用的多一点

文章对比了两种Vue实现方式:一种是不包含动画的transition-group,另一种则是带有过渡动画的。作者展示了如何使用`v-enter`和`v-leave`来控制列表项的进出动画效果,以及无缝滚动的实现方法。
摘要由CSDN通过智能技术生成

不注重动画的基于transition-group实现的方式:

没有过渡动画

<template>
  <div class="scroll-container">
    <transition-group tag="div" name="slide" class="scroll-list">
      <div class="scroll-item" v-for="(item, index) in items" :key="item.key">
        {{ item.text }}
      </div>
    </transition-group>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [], // 您的数据数组
      maxVisibleItems: 5, // 可视区域最多显示的条目数
    };
  },
  mounted() {
    this.initializeItems();
    this.startSeamlessScroll();
  },
  methods: {
    initializeItems() {
      // 初始化数据,确保有足够的条目来填充滚动列表
      for (let i = 1; i <= 10; i++) {
        this.items.push({ text: `条目${i}`, key: i });
      }
    },
    startSeamlessScroll() {
      // 设置定时器来更新列表,实现无缝滚动
      setInterval(() => {
        const firstItem = this.items.shift(); // 移除第一个元素
        this.items.push(firstItem); // 将第一个元素添加到列表末尾
      }, 2000); // 每2秒滚动一次
    },
  },
};
</script>

<style>
.scroll-container {
  overflow: hidden;
  height: 250px; /* 根据您的项目高度调整 */
}
.scroll-item {
  height: 50px; /* 根据您的项目高度调整 */
}
.scroll-list {
  display: flex;
  flex-direction: column;
}
.slide-enter-active,
.slide-leave-active {
  transition: all 0.5s ease;
}
.slide-enter,
.slide-leave-to {
  transform: translateY(100%);
  opacity: 0;
}
</style>

效果图:

有动画的基于transition-group的实现的方式:

有过渡动画

<template>
  <div class="scroll-view" @mouseenter="stopScroll" @mouseleave="startScroll">
    <transition-group name="list" tag="div" class="list-container">
      <div
        class="list-item"
        v-for="(item, index) in displayItems"
        :key="item.key"
      >
        {{ item.text }}
      </div>
    </transition-group>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [], // 这个数组会填入全部数据
      displayItems: [], // 这个数组用于展示可见的数据
      scrollInterval: null,
      pauseTime: 2000,
    };
  },
  created() {
    // 初始化 items,添加 key 用作 transition-group 的唯一标识
    this.items = Array.from({ length: 10 }, (v, k) => ({
      text: `Item ${k + 1}`,
      key: k,
    }));
    // 填充 displayItems 数组
    this.displayItems = [...this.items];
  },
  mounted() {
    this.startScroll();
  },
  methods: {
    scroll() {
      const firstItem = this.displayItems.shift(); // 移除数组的第一个元素
      this.displayItems.push(firstItem); // 将其添加到数组的末尾(无缝滚动的关键)

      // 如果我们到达列表的末尾,我们会重置按键以创建无缝体验 TODO 一开始因为vue的diff算法涉及到key,想着去更新dom,但实际这里会阻塞页面的渲染
      // if (this.displayItems[0].key === 0) {
      //   this.resetKeys();
      // }
    },
    startScroll() {
      // TODO 不想停留的话,去掉这些
      this.scrollInterval = setInterval(() => {
        this.scroll();
      }, this.pauseTime);
    },
    stopScroll() {
      clearInterval(this.scrollInterval);
    },
    resetKeys() {
      this.displayItems.forEach((item, index) => {
        item.key = index;
      });
      console.log("重置", this.displayItems);
    },
  },
  beforeDestroy() {
    this.stopScroll();
  },
};
</script>

<style scoped>
.scroll-view {
  overflow: hidden;
  height: 250px; /* Assumes each item is 50px in height and we show 5 items */
}

.list-container {
  padding: 0;
}

.list-item {
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: left;
  transition: transform 0.8s ease;
}

/* Animation for each list item */
.list-move {
  transition: transform 2s ease;
}

/* Set the distance each item has to move (should be the height of 1 item) */
.list-enter-active,
.list-leave-active {
  transition-duration: 0.8s;
}

.list-enter,
.list-leave-to /* <- this is the new Vue 2.1.8+ syntax for v-leave */ {
  transform: translateY(50px);
}
</style>

效果图:

其他的可以参考借鉴的例子:

https://codesandbox.io/p/sandbox/vue-template-pt5oz?file=%2Fsrc%2FApp.vue%3A11%2C1

https://juejin.cn/post/7253115535483207737#heading-8

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值