基于自身业务需求而开发的自动横向循环播放内容的组件 采用css 动画效果 可以自定义配置 每秒进步像素距离和首尾间距 展示
组件
<template>
<div class="notice-bar" ref="noticeBarRef">
<div class="notice-bar-content" ref="contentRef" :style="contentStyle">
<slot></slot>
<!-- 如果开启动画 内容循环 -->
<template v-if="animateFlag">
<span class="content-headway" :style="{ width: `${headway}px` }"></span>
<slot></slot>
</template>
</div>
</div>
</template>
<script>
export default {
name: 'notice-bar',
// 父组件传递数据
props: {
// 进步 每秒移动像素值
speed: {
type: Number,
default: 50
},
// 首尾间距
headway: {
type: Number,
default: 60
}
},
data () {
return {
contentStyle: {
transitionDuration: '0s',
transform: 'translateX(0px)'
},
contentWidth: 0,
time: 0,
timer: undefined,
animateFlag: false
}
},
// 方法集合
methods: {
// 初始化
init () {
// 容器宽度
const barWidth = this.$refs.noticeBarRef.offsetWidth
// 内容宽度
const contentWidth = this.$refs.contentRef.offsetWidth
if (contentWidth >= barWidth) {
// 内容宽度 + 间距
this.contentWidth = contentWidth + this.headway
this.animateFlag = true
this.openCycle()
}
},
// 开启循环
openCycle () {
// 内容宽度 / 进步数值 = 动画时长
this.time = this.contentWidth / this.speed
this.startAnimate()
// 循环
this.timer = setInterval(() => {
this.startAnimate()
}, this.time * 1000)
// 消除定时器
this.$once('hook:beforeDestroy', () => {
clearInterval(this.timer)
this.timer = null
})
},
// 开启动画
startAnimate () {
// 动画初始状态
this.contentStyle = {
transitionDuration: '0s',
transform: 'translateX(0px)'
}
// 动画开启 time 动画时间 contentWidth 动画长度
setTimeout(() => {
this.contentStyle = {
transitionDuration: `${this.time}s`,
transform: `translateX(-${this.contentWidth}px)`
}
}, 10)
}
},
// 生命周期 - 页面完成(可以访问当前dom实例)
mounted () {
this.init()
}
}
</script>
<style lang="scss" scoped>
.notice-bar {
position: relative;
display: flex;
flex: 1;
height: 100%;
align-items: center;
overflow: hidden;
&::after {
content: '';
width: 30px;
height: 100%;
position: absolute;
right: 0;
background: linear-gradient(270deg, #FFFFFF 0%, rgba(255, 255, 255, 0) 100%);
}
.notice-bar-content {
position: absolute;
white-space: nowrap;
transition-timing-function: linear;
.content-headway {
display: inline-block;
}
}
}
</style>
组件引用
<template>
<div class="stock-price-info">
<notice-bar :width="info.width">
<span>平安银行(000001)</span>
<span>2022-08-31 14:52</span>
<span>最新股价:15.52</span>
<span>涨跌情况:-0.54/1.54%</span>
<span>最高:17.45</span>
<span>最低:16.33</span>
<span>今开:16.88</span>
<span>昨收:16.88</span>
<span>换手率:15.23%</span>
<span>成交量:25,245,234</span>
<span>成交额:12.52亿元</span>
</notice-bar>
</div>
</template>
<script>
import NoticeBar from '@/components/contentBasics/NoticeBar'
export default {
// import引入的组件需要注入到对象中才能使用
components: { NoticeBar },
}
</script>
<style lang="scss" scoped>
.stock-price-info {
padding: 0 16px;
display: flex;
align-items: center;
background-color: #fff;
border-radius: 3px;
}
</style>