本文实例为大家分享了vue开发实现跑马灯效果组件的具体代码,供大家参考,具体内容如下

用vue编写一个可以快进后退的跑马灯组件

由于业务需求,要实现一个会可以控制速度的跑马灯,初开始用js的setinterval每隔几毫秒来减取一个字符拼接到后面,效果不理想就放弃了。后查询用js的animate这个api改造大功告成!

效果图

组件代码

<template>    <div class="marquee" @mouseover="pause(true)" @mouseleave="pause()">      <i        class="marquee-btn btn-left el-icon-d-arrow-left"        @mousedown="speedUp(true)"        @mouseup="speedStop()"      ></i>      <div ref="marqueeText" class="marquee-text">        <div v-if="itemClick">          <span            v-for="item in text.split(splitSymbol)"            :key="item"            @click="$emit('itemClickEvent', item)"          >{{item + ' 、'}}</span>        </div>        <div v-else>{{text}}</div>      </div>      <i        class="marquee-btn btn-right el-icon-d-arrow-right"        @mousedown="speedUp()"        @mouseup="speedStop()"      ></i>    </div>  </template>    <script>  export default {    name: "marquee",    props: {      text: {        type: String,        required: true      },      speed: {        type: Number,        required: false,        default: 110      },      // 是否每个都可以点击触发事件      itemClick: {        type: Boolean,        required: false,        default: false      },      // 每个触发事件元素的分割符号      splitSymbol: {        type: String,        required: false,        default: ''      }    },    data() {      return {        aniInstance: null,        speedTimer: null      };    },    methods: {      setAnimate() {        const contentWidth = this.$refs.marqueeText.scrollWidth;        const keyframes = [          { transform: "translateX(100%)" },          { transform: `translateX(-${contentWidth}px)` }        ];        const animateOptions = {          duration: (contentWidth / this.speed) * 1000,          iterations: Infinity,          easing: "linear"        };        this.aniInstance = document.querySelector(".marquee-text").animate(keyframes, animateOptions);      },      /**       * 快进       * @param { Boolean } isLeft 是否为左方向       */      speedUp(isLeft = false) {        const set = () => {          if (this.aniInstance.currentTime > 0) {            this.aniInstance.currentTime = this.aniInstance.currentTime + (isLeft ? 2000 : -2000);            this.aniInstance.currentTime <= 0 && (this.aniInstance.currentTime = 0);          }        }        // 鼠标单击        set();        // 鼠标长按        this.speedTimer = setInterval(() => {          set()        }, 100);      },      // 快进停止      speedStop() {        clearInterval(this.speedTimer);        this.speedTimer = null;      },      /**       * 暂停、播放       * @param { Boolean } isPause 是否暂停       */      pause(isPause = false) {        this.aniInstance[["play", "pause"][Number(isPause)]]();      }    },    mounted() {      this.$nextTick(() => {        this.setAnimate();      });    }  };  </script>    <style lang="less" scoped>  .marquee {    position: relative;    padding: 10px 0;    overflow: hidden;    width: 100%;    font-size: 16px;    color: #fff;    background-image: linear-gradient(      to left,      #b9565e,      #cb655a,      #da7655,      #e58a50,      #eb9f4b    );    &:hover .marquee-btn {      opacity: 1;    }  }  .marquee-btn {    position: absolute;    top: 50%;    transform: translateY(-50%);    padding: 15px;    color: #fff;    background: rgba(1, 1, 1, 0.4);    z-index: 999;    cursor: pointer;    opacity: 0;    transition: all 0.2s linear;  }  .btn-left {    left: 0;  }  .btn-right {    right: 0;  }  .marquee-text {    white-space: nowrap;    span {      &:hover {        cursor: pointer;        color: #2c3e50;      }    }  }  </style>

父组件代码

<Marquee    :text="overdueInfo.content"    :itemClick="true"    :speed="120"    splitSymbol="、"    @itemClickEvent="marqueeSearch"    class="marquee-box__container"  ></Marquee>