前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue 实现单行向上滚动

Vue 实现单行向上滚动

作者头像
上山打老虎了
发布2022-06-15 08:42:27
1.5K0
发布2022-06-15 08:42:27
举报
文章被收录于专栏:Article

这个单行轮播是在之前多行轮播的基础上迭代的,本质上二者的思路都相同的,解决了核心重复轮播的算法后,剩下的就是样式的调整。

以前会用重复 dom 的方式来实现轮播,后来受到一个轮播插件的方案的启发,首先我们补齐 dom 的方式本质上还是在补齐需要重复的数据,所以在 Vue 中我们可以先根据你的轮播方式,

  1. 计算出需要追加的重复元素
  2. 计算出重复元素开始在可视区域后(即第一轮的数据展示的位置和当前重复元素的展示位置一致时)通过 css 将 dom 的位置「闪现」复位

在没有过渡动画的加持下,元素的位移肉眼无法察觉,所以我们又可以开始新一轮的轮播。

https://www.noxxxx.com/wp-content/uploads/2020/03/broad-cast.mov

代码语言:javascript
复制
<template>
  <div
    class="scroll-container"
    :style="{height: `${height/100}rem`}"
  >
    <ul
      v-for="(item, index) in list"
      :key="index"
      class="scroll-ul"
      :style="{transform: `translate3d(0, ${y/100}rem, 0)`, transition: `${transition}`}"
    >
      <li
        class="c-item"
      >
        <img
          v-if="item.content"
          class="a-item"
          :src="item.avatar"
        >
        <div
          v-if="item.content"
          class="c-content"
          v-html="item.content"
        />
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'broad-cast',
  props: {
    list: {
      type: Array,
      default: function () {
        return []
      }
    }
  },
  data () {
    return {
      height: 0, // 单项高度
      y: 0, // 每次移动距离
      originLength: 0, // 原始数组长度
      transition: 'ease all .4s',
      number: 1, // 默认一次滚动一条
      interval: null
    }
  },
  mounted () {
    this.init()
    this.scroll()
  },
  methods: {
    init () {
      if (!this.list.length) return
      this.originLength = this.list.length
      const mod = this.originLength % this.number
      let need = this.originLength < this.number ? (this.number - this.originLength + this.number) : mod === 0 ? (this.number + 1) : (this.number - mod + this.number)
      // 按次序从头开始补齐
      let index = 0
      for (let i = 0; i < need; i++) {
        if (this.list[i]) {
          index = i
        } else {
          index = 0
        }
        const tmp = JSON.parse(JSON.stringify(this.list[index]))
        index++
        this.list.push(tmp)
      }
    },
    scroll () {
      if (!this.list.length) return
      // 计算可视区域高度
      this.height = 64 * this.number + (12 * (this.number - 1))
      let count = 0
      this.y = 0
      clearInterval(this.interval)
      this.interval = setInterval(() => {
        count++
        this.y -= (64 + 12)
        this.transition = '.4s ease all'
        setTimeout(() => {
          if (count === (this.originLength)) {
            count = 0
            this.transition = ''
            this.y = 0
          }
        }, 800)
      }, 2000)
    }
  }
}
</script>

<style scoped lang="scss">
  .scroll-container {
    overflow: hidden;
  }
  .c-item {
    display: flex;
    align-items: center;
    height: .64rem;
    box-sizing: border-box;
    margin-bottom: .12rem;
    color: #223875;
  }
  .c-content {
    max-width: 4.4rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .a-item {
    border-radius: 50%;
    overflow: hidden;
    width: .42rem;
    height: .42rem;
    margin-right: .14rem;
  }
</style>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020年03月07日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档