vue大屏轮播(跑马灯)实现思路

8,486次阅读
没有评论

共计 6472 个字符,预计需要花费 17 分钟才能阅读完成。

需求背景:例如大屏需要显示一周的排班信息、菜单信息、亦或者轮播展示某个部门的员工信息,这时候需要进行跑马灯似的无缝滚动效果

实现方式一
@keyframes ygmove {
  to {
    transform: translateX(-1700px); // 规定 ygmove 动画是在 x 轴负方向移动 1700px 的距离
  }
}
template>
  div>
    div class="yg-list flex">
      div class="yg-content">
        div class="yg-content-move flex">
          div 
            class="yg-item flex" 
            v-for="(ygItem, ygIndex) in ygData" 
            :key="ygIndex"
          >
            div class="yg-info flex">
              div class="yg-img">
                img :src="ygItem.headImg" alt="">
              div>
              div class="yg-name">{{ygItem.name}}div>
              div class="yg-gangwei">{{ygItem.yggangweiEnumValue}}div>
            div>
            div class="yg-zheng-pic">
              img :src="ygItem.zhengshiUrl" alt="">
            div>
          div>
        div>
      div>
    div>
  div>
template>

script>
export default {
  data() {
    return {
      ygData: [
        {
          headImg: require('../src/assets/zheng-em-man.png'),
          zhengshiUrl: 'https://wx2.sinaimg.cn/mw690/005Dg9pggy1hqv02dv5pkj32vo2vokc6.jpg',
          name: '动作 1',
          yggangweiEnumValue: '保姆'
        }, {
          headImg: require('../src/assets/zheng-em-man.png'),
          zhengshiUrl: 'https://ww2.sinaimg.cn/mw690/005Dg9pggy1hqv02lw9elj33pc3pcb29.jpg',
          name: '动作 2',
          yggangweiEnumValue: '保姆'
        }, {
          headImg: require('../src/assets/zheng-em-man.png'),
          zhengshiUrl: 'https://wx4.sinaimg.cn/mw690/005Dg9pggy1hqv02i51fej33pc3pce81.jpg',
          name: '动作 3',
          yggangweiEnumValue: '保姆'
        }, {
          headImg: require('../src/assets/zheng-em-man.png'),
          zhengshiUrl: 'https://ww2.sinaimg.cn/mw690/005Dg9pggy1hqv02lw9elj33pc3pcb29.jpg',
          name: '动作 4',
          yggangweiEnumValue: '保姆'
        }, {
          headImg: require('../src/assets/zheng-em-man.png'),
          zhengshiUrl: 'https://wx4.sinaimg.cn/mw690/005Dg9pggy1hqv02i51fej33pc3pce81.jpg',
          name: '动作 5',
          yggangweiEnumValue: '保姆'
        }, {
          headImg: require('../src/assets/zheng-em-man.png'),
          zhengshiUrl: 'https://wx2.sinaimg.cn/mw690/005Dg9pggy1hqv02dv5pkj32vo2vokc6.jpg',
          name: '动作 1',
          yggangweiEnumValue: '保姆'
        }, {
          headImg: require('../src/assets/zheng-em-man.png'),
          zhengshiUrl: 'https://ww2.sinaimg.cn/mw690/005Dg9pggy1hqv02lw9elj33pc3pcb29.jpg',
          name: '动作 2',
          yggangweiEnumValue: '保姆'
        }
      ]
    }
  },
  methods: {}
}
script>

style scoped lang="scss">

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

::-webkit-scrollbar {
  width: 0 !important;
}
::-webkit-scrollbar {
  width: 0 !important;
  height: 0;
}
.flex {
  display: flex;
}
.yg-list {
  padding: 15px; 
  width: 712px;
  height: 180px;
  background: linear-gradient(0deg, rgba(0, 115, 255, 0.59) 0%, rgba(0, 140, 255, 0) 100%);
  border: 1px solid #5FB2FF;
  overflow-x: scroll;
  white-space: nowrap;
  .yg-content {
    width: 1000px;
    height: 150px;
    overflow: hidden;
    .yg-content-move {
      // ygmove 动画名
      // 10s 动画完成一个周期所花费的秒或毫秒
      // infinite 动画被播放的次数
      // linear 规定动画的速度曲线
      animation: ygmove 10s infinite linear;
    }
  }
  .yg-item {
    flex-shrink: 0;
    padding: 12px;
    margin-right: 20px;
    width: 320px;
    height: 148px;
    border: 1px solid rgba(0, 229, 255, 0.5);
    .yg-info {
      justify-content: space-between;
      flex-direction: column;
      align-items: center;
      margin-right: 15px;
      width: 78px;
      height: 124px;
      font-size: 14px;
      color: #fff;
      .yg-img {
        width: 78px;
        height: 78px;
        border-radius: 4px;
        box-shadow: 0px 0px 5px 0px #00E5FF;
        overflow: hidden;
      }
    }
    .yg-zheng-pic {
      width: 203px;
      height: 124px;
      border-radius: 4px;
      overflow: hidden;
      img {
        width: 100%;
        height: 100%;
      }
    }
  }
}

@keyframes ygmove {
  to {
    transform: translateX(-1700px);
  }
}
style>
实现方式二
  • 使用 vue-seamless-scroll(推荐)
  • 步骤
  1. 下包
--> npm
npm install vue-seamless-scroll --save

--> yarn
yarn add vue-seamless-scroll

--> cdn
https://cdn.jsdelivr.net/npm/vue-seamless-scroll@latest/dist/vue-seamless-scroll.min.js
  1. 引入组件


import seamlessScroll from 'vue-seamless-scroll'
Vue.use(seamlessScroll)
  1. 使用
template>
  div>
    
    
    div class="yg-list flex">
      div class="yg-content">
        vue-seamless-scroll :data="ygData" class="yg-content" :class-option="defaultOption">
            div class="yg-content-move flex">
              div 
                class="yg-item flex" 
                v-for="(ygItem, ygIndex) in ygData" 
                :key="ygIndex"
              >
                div class="yg-info flex">
                  div class="yg-img">
                    img :src="ygItem.headImg" alt="">
                  div>
                  div class="yg-name">{{ygItem.name}}div>
                  div class="yg-gangwei">{{ygItem.yggangweiEnumValue}}div>
                div>
                div class="yg-zheng-pic">
                  img :src="ygItem.zhengshiUrl" alt="">
                div>
              div>
            div>
          vue-seamless-scroll>
      div>
    div>
  div>
template>

script>

export default {
  
  data() {
    return {
      ygData: [
        {
          headImg: require('../src/assets/zheng-em-man.png'),
          zhengshiUrl: 'https://wx2.sinaimg.cn/mw690/005Dg9pggy1hqv02dv5pkj32vo2vokc6.jpg',
          name: '动作 1',
          yggangweiEnumValue: '保姆'
        }, {
          headImg: require('../src/assets/zheng-em-man.png'),
          zhengshiUrl: 'https://ww2.sinaimg.cn/mw690/005Dg9pggy1hqv02lw9elj33pc3pcb29.jpg',
          name: '动作 2',
          yggangweiEnumValue: '保姆'
        }, {
          headImg: require('../src/assets/zheng-em-man.png'),
          zhengshiUrl: 'https://wx4.sinaimg.cn/mw690/005Dg9pggy1hqv02i51fej33pc3pce81.jpg',
          name: '动作 3',
          yggangweiEnumValue: '保姆'
        }, {
          headImg: require('../src/assets/zheng-em-man.png'),
          zhengshiUrl: 'https://ww2.sinaimg.cn/mw690/005Dg9pggy1hqv02lw9elj33pc3pcb29.jpg',
          name: '动作 4',
          yggangweiEnumValue: '保姆'
        }, {
          headImg: require('../src/assets/zheng-em-man.png'),
          zhengshiUrl: 'https://wx4.sinaimg.cn/mw690/005Dg9pggy1hqv02i51fej33pc3pce81.jpg',
          name: '动作 5',
          yggangweiEnumValue: '保姆'
        }, {
          headImg: require('../src/assets/zheng-em-man.png'),
          zhengshiUrl: 'https://wx2.sinaimg.cn/mw690/005Dg9pggy1hqv02dv5pkj32vo2vokc6.jpg',
          name: '动作 1',
          yggangweiEnumValue: '保姆'
        }, {
          headImg: require('../src/assets/zheng-em-man.png'),
          zhengshiUrl: 'https://ww2.sinaimg.cn/mw690/005Dg9pggy1hqv02lw9elj33pc3pcb29.jpg',
          name: '动作 2',
          yggangweiEnumValue: '保姆'
        }
      ],
    }
  },
  computed: {
    
    defaultOption () {
      return {
        step: 10, 
        limitMoveNum: this.ygData.length, 
        hoverStop: true, 
        direction: 2, 
        openWatch: true, 
        singleHeight: 0, 
        singleWidth: 0, 
        waitTime: 1000, 
        delay: 0
      }
    }
  }
}
script>

style scoped lang="scss">

* {
  margin: 0;
  padding: 0;
  
  box-sizing: border-box;
}

::-webkit-scrollbar {
  width: 0 !important;
}
::-webkit-scrollbar {
  width: 0 !important;
  height: 0;
}
.flex {
  display: flex;
}
.yg-list {
  padding: 15px; 
  width: 712px;
  height: 180px;
  background: linear-gradient(0deg, rgba(0, 115, 255, 0.59) 0%, rgba(0, 140, 255, 0) 100%);
  border: 1px solid #5FB2FF;
  overflow-x: scroll;
  white-space: nowrap;
  .yg-content {
    width: 1000px;
    height: 150px;
    overflow: hidden;
    .yg-content-move {
      // animation: ygmove 5s infinite ease-in;
    }
  }
  .yg-item {
    flex-shrink: 0;
    padding: 12px;
    margin-right: 20px;
    width: 320px;
    height: 148px;
    // background-color: orange;
    border: 1px solid rgba(0, 229, 255, 0.5);
    .yg-info {
      justify-content: space-between;
      flex-direction: column;
      align-items: center;
      margin-right: 15px;
      width: 78px;
      height: 124px;
      font-size: 14px;
      color: #fff;
      .yg-img {
        width: 78px;
        height: 78px;
        border-radius: 4px;
        box-shadow: 0px 0px 5px 0px #00E5FF;
        overflow: hidden;
      }
    }
    .yg-zheng-pic {
      width: 203px;
      height: 124px;
      border-radius: 4px;
      overflow: hidden;
      img {
        width: 100%;
        height: 100%;
      }
    }
  }
}

// @keyframes ygmove {
//   to {
//     transform: translateX(-1700px);
//   }
// }

// .yg-content:hover .yg-content-move {
//   animation-play-state: paused;
// }
style>

两者的比较

通过 css 的方式不太灵活,第一种方法适用于轮播数量已知的情况下,存在以下问题

  1. 它需要根据滚动窗口大小对滚动数据追加相应的前几条数据方便实现无缝效果,例如滚动窗口可以看到两个滚动卡片,一共五个卡片,当五个卡片滚动完一次后会出现滚动窗口留白的情况,因为滚动窗口可以看到两个卡片,需要将前两个卡片数据追加到数据末尾来填充留白问题
  2. 而且在数据不确定的情况下,动画时间也需要进行相应设置例如数据有五条,动画设置 5s 完成就行,当数据变成 10 条时,动画完成时间还是 5s,造成速度是之前的二倍

尽管可以根据数据量不同来操作 dom 设置这些数据,但还是相对麻烦的,而相比来说第二种方式可以动态设置数据量以及速度,避免了之前的问题

原文地址: vue 大屏轮播(跑马灯)实现思路

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-10-29发表,共计6472字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)