vue组件-利用animation实现跑马灯效果

3,942 阅读2分钟
  • 码云地址(demo实例): gitee.com/big-sun/ani…
  • 目标
    • vue组件
    • 样式父组件自定义
    • 留出自定义的样式的空间
    • 要能支持跳转
    • 当鼠标进入跑马灯的时候,跑马灯暂停,离开启动
  • 效果

父组件文件传入的数据格式

 <graphic-animation :dataArr="dataArr"></graphic-animation>
 dataArr: [
        {
          inner:
            "1、平台累计加载数据集161个,数据量达1765.76GB,覆盖10大学科领域,时间跨度从1662年至今,空间范围覆盖全球海域。",
            url:'http://www.baidu.com/platDetail.html#d47b95551d1f4293bc2898d518f677e5'
        },
        {
          inner:
            "2、第七届中国科学数据大会将于2020年8月19-21日在内蒙古和林格尔新区召开,诚邀您的参加。",
            url:'http://www.baidu.com/pages/platDetail.html#aceadecbb051430ead23ff9869581f14'
        },
        {
          inner:
            "3、国家海洋科学数据中心入围2019年度中国十大海洋科技进展。",
            url:http://www.baidu.com/pages/platDetail.html#5ebeceaa2e9145339fe19950de7dfd71'
        }
      ]

跑马灯组件 .vue文件

<template>
  <div class='animation-horse-race-lamp'>
    <p
      :style="animation"
      @mouseenter="mouseenter"
      @mouseleave="mouseleave"
    >
      <a
        v-for="(item,index) in dataArr"
        :href="item.url"
        :key="index"
      >
        <span>{{item.inner}}</span>
      </a>
    </p>
  </div>
</template>
<style src='./normalize.css'></style>//清楚默认样式的css库文件
<style lang='scss' scoped>
.animation-horse-race-lamp {//组件默认的样式
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
  p {
    position: absolute;
    white-space: nowrap;
    cursor: pointer;
    a{
        text-decoration: none;
        color: #000;
    }
  }
}
</style>
<style src='./index.css'></style>//使用本组件的用户定义的样式
<script src='./animation-horse-race-lamp.js'></script>

跑马灯组件 .animation-horse-race-lamp.js文件

    export default {
    name: '',
    props: {
      dataArr: {
        type: Array,
        require: true
      }
    },
    data() {
      return {
        msg: '这里是 组件名称 组件',
        pStyle: {
          "animation": '',
          "animation-play-state": 'running'
        }
      };
    },
    created() {}, //初始化数据,发送Ajax
    mounted() {
      this.init()
    }, //window.onload
    activated() {}, //必须基于keep-alive使用功能近似于beforeRouteEnter
    components: {}, //组件注册
    computed: {
      animation() {
        let str = ''
        for (let [key, value] of Object.entries(this.pStyle)) {
          str += `${key}:${value}`
        }
        return str
      }
    }, //计算属性
    filters: {}, //过滤器
    watch: {
      route(to, from) {},
      dataArr: {
        handler(newName, oldName) {
          if (newName.length == this.dataArr.length) {
            this.init()
          }
        },
        immediate: true,
        deep: true
      }
    }, //组件进入还是离开都会被监听到,当前路由改变,但是该组件被复用时调用(动态参数的路径功能等同于beforeRouteUpdate(to, from, next){})

    methods: {
      init() {
        this.$nextTick(() => {
          let animationHorseRaceLampWidth = document.querySelector('.animation-horse-race-lamp').offsetWidth;
          let translateX = (document.querySelector('.animation-horse-race-lamp>p').offsetWidth - animationHorseRaceLampWidth) + 'px';
          if (parseInt(translateX) > 0) {
            this.pStyle.animation = `run ${parseInt(translateX)/parseInt(animationHorseRaceLampWidth)*10}s linear 0ms infinite;`
            document.styleSheets[0].insertRule(`
          @keyframes run {
                  0% {
                      transform: translateX(0);
                  }
                  100% {
                      transform: translateX(-${translateX});
                  }
              }
      `, 1)
          }
        })
      },
      mouseenter() {
        this.$set(this.pStyle, "animation-play-state", 'paused')
      },
      mouseleave() {
        this.$set(this.pStyle, "animation-play-state", 'running')
      }
    } //方法
  }