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

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

实现方式一
  • 使用css动画结合关键帧进行实现

  • animation的常见属性

    • animation-name 动画名称
    • animation-duration 规定动画完成一个周期所花费的秒或毫秒
    • animation-iteration-count 规定动画被播放的次数
      • 可以是整数或者小数
      • infinite 无限
    • animation-timing-function 规定动画的速度曲线
      • ease(默认)动画以低速开始,然后加快,在结束前变慢,速度类似正态分布曲线
      • linear 匀速运动
      • ease-in 低速开始、
      • ease-out 低速结束
      • ease-in-out 动画以低速开始和结束
      • steps 指定了时间函数中的间隔数量(步长)(动画分几步完成)
    • animation-play-state 规定动画是否正在运行或暂停。默认是" running" 还有’ paused 暂停
      • 可以制作当鼠标移除轮播区域是进行动画暂停,提高用户体验
  • 可以进行简写(推荐)

    • animation: ygmove 10s infinite linear;
@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. 引入组件
// main.js
// 在main.js中引入 作为全局
import seamlessScroll from 'vue-seamless-scroll'
Vue.use(seamlessScroll)
  1. 使用
<template>
  <div>
    <!-- 消息滚动组件,区域多大它滚动的地方就有多大 -->
    <!-- <test-scroll></test-scroll> -->
    <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>
// import TestScroll from './components/TestScroll.vue'
export default {
  // components: { TestScroll },
  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 可以写在data中的,但是需要获取滚动数量,因此写在computed中
    defaultOption () {
      return {
        step: 10, // 数值越大速度滚动越快
        limitMoveNum: this.ygData.length, // 开始无缝滚动的数据量 this.dataList.length
        hoverStop: true, // 是否开启鼠标悬停stop
        direction: 2, // 0向下 1向上 2向左 3向右
        openWatch: true, // 开启数据实时监控刷新dom
        singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
        singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
        waitTime: 1000, // 单步运动停止的时间(默认值1000ms)
        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设置这些数据,但还是相对麻烦的,而相比来说第二种方式可以动态设置数据量以及速度,避免了之前的问题

Vue3是一种流行的JavaScript框架,用于构建用户界面。它具有响应式数据绑定和组件化的特性,使得开发者可以更轻松地构建交互式的Web应用程序。 CSS跑马灯轮播图是一种常见的网页元素,用于展示多张图片或内容,并以动画的方式进行切换。在Vue3中,可以通过以下步骤来实现CSS跑马灯轮播图: 1. 创建一个Vue组件,命名为Carousel。 2. 在组件中定义一个data属性,用于存储轮播图的数据,例如图片的URL或者内容。 3. 在组件的模板中使用v-for指令,遍历轮播图数据,并生成对应的DOM元素。 4. 使用CSS样式设置轮播图容器的宽度和高度,并设置overflow属性为hidden,以隐藏超出容器范围的内容。 5. 使用CSS动画或过渡效果,实现轮播图的切换效果。可以使用@keyframes定义动画序列,或者使用transition属性设置过渡效果。 6. 在组件的生命周期钩子函数中,使用定时器或其他方式,控制轮播图的自动切换。 下面是一个简单的示例代码: ```html <template> <div class="carousel"> <div class="slide" v-for="(item, index) in carouselData" :key="index"> <!-- 轮播图内容 --> <img :src="item.image" alt="carousel image" /> </div> </div> </template> <script> export default { data() { return { carouselData: [ { image: 'image1.jpg' }, { image: 'image2.jpg' }, { image: 'image3.jpg' }, ], }; }, }; </script> <style> .carousel { width: 100%; height: 300px; overflow: hidden; } .slide { width: 100%; height: 100%; animation: carouselAnimation 10s infinite; } @keyframes carouselAnimation { 0% { transform: translateX(0); } 33% { transform: translateX(-100%); } 66% { transform: translateX(-200%); } 100% { transform: translateX(0); } } </style> ``` 这是一个简单的Vue3 CSS跑马灯轮播图的实现示例。你可以根据自己的需求进行样式和动画的调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不断蜕变灬青春

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值