第一种:纯文字展示,只有一句话
效果图
<!-- 公告栏组件 -->
<template>
<div class="notice-bar" @click="tipClick">
<div class="notice-bar__icon">
<img src="@/assets/icons/notice.png"/>
<span>{{ sub_title }}</span>
</div>
<div ref="wrap" class="notice-bar__wrap">
<div ref="content" class="notice-bar__content" :style="contentStyle">{{ text }}</div>
</div>
</div>
</template>
<script>
export default {
name: 'NoticeBar',
props: {
sub_title: {
type: String,
default: '通知:'
},
text: {
type: String,
default: ''
},
speed: {
type: Number,
default: 50
},
defaultWidth: {
type: Number,
default: 375
}
},
data () {
return {
contentStyle: {
transitionDuration: '0s',
transform: 'translateX(0px)'
},
wrapWidth: 0,
contentWidth: 0,
time: 0,
timer: null,
convertSpeed: 1
}
},
created () {},
mounted () {
if (this.text) {
this.init()
}
},
watch: {
text (val) {
this.init()
}
},
methods: {
init () {
const _width = window.innerWidth
this.convertSpeed = _width / this.defaultWidth * this.speed // 根据分辨率转化成不同的速度
this.wrapWidth = this.$refs.wrap.offsetWidth
this.contentWidth = this.$refs.content.offsetWidth
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'
this.contentStyle.transform = 'translateX(' + this.wrapWidth + 'px)'
this.time = (this.wrapWidth + this.contentWidth) / this.convertSpeed
setTimeout(() => {
this.contentStyle.transitionDuration = this.time + 's'
this.contentStyle.transform = 'translateX(-' + this.contentWidth + 'px)'
}, 200)
},
tipClick () {
this.$emit('click')
}
}
}
</script>
<style scoped lang='scss'>
.notice-bar {
position: relative;
width: 100%;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #eee;
display: flex;
align-items: center;
.notice-bar__icon {
display: flex;
align-items: center;
img {
width: 20px;
margin-right: 10px;
}
}
.notice-bar__wrap {
position: relative;
display: flex;
flex: 1;
height: 100%;
align-items: center;
overflow: hidden;
.notice-bar__content {
position: absolute;
color: #eee;
white-space: nowrap;
transition-timing-function: linear;
}
}
}
</style>
父组件中使用
// 引入
import noticeBar from '@/views/my_components/noticeBar.vue'// 消息滚屏
// 注册组件
components:{ noticeBar }
// 使用
<notice-bar :speed="20" v-if="noticeCon" :text="noticeCon" @click="openTip" />
// 数据
noticeCon: 'import NoticeBar from @/components/NoticeBarimport NoticeBar from @/components/NoticeBar',
// 方法
openTip () {}
第二种: 消息列表在滚屏上横向滚动
效果图:
子组件
<template>
<div class="m-slide" @mouseenter="onStop" @mouseleave="onStart">
<div
:style="`will-change: transform; transform: translateX(${-left}px);`"
class="u-slide-title"
v-for="(item, index) in sliderData"
:key="index"
:title="item.title"
@click="onClickTitle(item.title)">
{{ item.title }}
</div>
</div>
</template>
<script>
export default {
name: 'Slider',
props: {
sliderData: {
type: Array,
default: () => {
return []
}
}
},
data () {
return {
left: 0,
moveTimer: null
}
},
created () {
this.onStart()
},
methods: {
onClickTitle (title) { // 通知父组件点击的标题
this.$emit('getTitle', title)
},
onStop () { // 暂停滚动
clearInterval(this.moveTimer)
},
onStart () { // 开始滚动
if (this.sliderData.length > 4) { // 超过4条开始滚动
this.getSlide()
}
},
getSlide () {
this.moveTimer = setInterval(() => {
this.moveLeft()
}, 5) // 1s移动200次
},
moveLeft () {
if (this.left >= 320) {
this.sliderData.push(this.sliderData.shift()) // 将第一条数据放到最后
this.left = 0
} else {
this.left += 0.2 // 每次移动0.2px
}
}
}
}
</script>
<style lang="scss" scoped>
.m-slide {
width: 1200px;
margin: 60px auto;
height: 45px;
white-space: nowrap;
overflow: hidden;
.u-slide-title {
display: inline-block;
margin-left: 20px;
font-size: 14px;
font-weight: 400;
line-height: 45px;
// width: 300px;
// overflow: hidden;
// text-overflow: ellipsis;
// white-space: nowrap;
cursor: pointer;
&:hover {
color:#1890FF;
}
}
}
</style>
父组件中使用
// 引入
import Slider from '@/views/my_components/Slider.vue'// 消息滚屏
// 注册组件
components:{ Slider }
// 使用
<div class="notice item_box">
<img src="@/assets/icons/notice.png" alt="">
<div class="tit">通知:</div>
<div class="notice_con"><Slider :sliderData="sliderData" @getTitle="getSliderTitle"/></div>
</div>
// 数据
sliderData: [
{
title: '1美国作家杰罗姆·大卫·塞林格创作的唯一一部长篇小说'
},
{
title: '2首次出版于1951年'
},
{
title: '3天时间内'
},
{
title: '4内心世界'
},
{
title: '5在青少年中引起强烈共鸣'
}
],
// 方法
getSliderTitle (title) { // 获取点击的标题
console.log('title:', title)
},
样式
.notice{
display: inline-flex;
align-items: center;
padding: 0 20px;
height: 50px;
overflow: hidden;
img{
margin-right: 10px;
}
.tit{
width: 50px;
}
.notice_con{
width: 93%;
padding-right: 20px;
white-space: nowrap;
overflow: hidden;
}
}