转自:https://www.jianshu.com/p/a68819f143ac

子组件Scroller

滚动文字template(小喇叭megaphone我用的是iview的图标,所以我加了个注释)

<template>
  <div class="wrap">
    <!--<div id="megaphone">
      <Icon type="md-megaphone" color="gray" size="20"/>
    </div>-->
    <div id="box">
      <div id="marquee">{{text}}</div>
    </div>
    <div id="node">{{text}}</div>
  </div>
</template>

script部分

<script type="text/ecmascript-6">
export default {
  name: 'Scroller',
  props: ['lists'], // 父组件传入数据, 数组形式 [ "连雨不知春去","一晴方觉夏深"]
  data () {
    return {
      text: '', // 数组文字转化后的字符串
      list: ['欢迎访问长夜个人博客!!!']   //默认的滚动文字
    }
  },
  methods: {
    move () {
      // 获取文字text 的计算后宽度  (由于overflow的存在,直接获取不到,需要独立的node计算)
      let boxWidth = document.getElementById('box').getBoundingClientRect().width   //box的宽度
      let nodeWidth = document.getElementById('node').getBoundingClientRect().width   //文字的宽度
      let box = document.getElementById('box')
      let distance = 0 // 初始化位置
      // 定时器设置位移
      setInterval(function () {
        distance = distance + 1
        // 文字从左到右滚动播放
        if (distance >= boxWidth) {
          distance = -nodeWidth
        }
        box.style.transform = 'translateX(' + distance + 'px)'   // 沿x轴运动
      }, 40)
    }
  },
  // 把父组件传入的arr转化成字符串
  mounted: function () {
    this.list = this.lists
    for (let i = 0; i < this.list.length; i++) {
      this.text += '  ' + this.list[i]
    }
  },
  // 更新的时候运动
  updated: function () {
    this.move()
  }
}
</script>

样式参考

<style scoped>
.wrap {
  overflow: hidden;
  color: #005bbe;
}
#megaphone {
  float:left;
}
#box {
  /*width: 100%;*/
  width: 600px;
  float: left;
  height: 100%;
  white-space: nowrap;
}
#box div {
  float: left;
}
#marquee {
  margin: 0 16px 0 20px;
}
#node {
  position: absolute;
  z-index: -99;
  top: -99px;
}
</style>

父组件引用子组件

<template>
  <Row>
    <div style="margin-left: 40px; float: left">
      <Scroller :lists="list" v-if="list.length"></Scroller>
    </div>
    ...
  </Row>
</template>

import Scroller from '@/path/Scroller'
export default {
  components: {
    Scroller
  },
  data () {
    return {
      list: [],
    }
  },
  ...

说明

因为考虑到滚动文字的list可能是ajax请求异步获取的,子组件只在mount时取一次父组件传过来的lists参数,那么得到的lists就是个空数组。

watch
一开始我在子组件中用了watch,监听props 的lists,但实际使用起来会造成滚动文字闪烁(一卡一卡的,目测是watch配上异步的定时器的锅),而且这么做也挺耗客户端性能的。我们也并不需要实时监听lists,只想在ajax请求得到结果后,再加载子组件罢了。

v-if
忽然就想到了v-if,当v-if=false(null,[],0)时,不加载相应的组件,当v-if=true(非空)时才加载,妙啊,就是它了。

Logo

前往低代码交流专区

更多推荐