演示效果
封装的组件
<!--
* @Author:
* @Date: 2024-03-21 19:21:58
* @LastEditTime: 2024-03-21 20:31:50
* @LastEditors: Please set LastEditors
* @Description: 消息左右滚动
-->
<template>
<div
id="textScroll"
class="text-scroll"
@mousemove="inBox"
@mouseleave="leaveBox"
>
<div
v-for="i in 2"
:id="'scrollItem' + i"
:key="'scrollItem' + i"
class="scroll-item"
:style="{ display: i === 1 ? 'flex' : 'none' }"
>
<slot></slot>
</div>
</div>
</template>
<script>
export default {
components: {},
data() {
return {
left: 0,
textScrollDiv: null,
timer: null,
scrollItemWidth: 0,
isScroll: false
};
},
computed: {},
destroyed() {
clearInterval(this.timer);
},
mounted() {
const that = this;
this.$nextTick(() => {
that.textScrollDiv = document.querySelector('#textScroll');
that.scrollItemWidth = document.querySelector('#scrollItem1').clientWidth;
const outerBoxWidth = that.textScrollDiv.clientWidth;
if (outerBoxWidth < that.scrollItemWidth) {
this.isScroll = true;
that.textScrollDiv.style.width = `${that.scrollItemWidth * 2}px`;
that.timer = setInterval(function() {
that.moveLeft();
}, 30);
document.querySelector('#scrollItem2').style.display = 'flex';
}
});
},
methods: {
moveLeft() {
if (this.textScrollDiv) {
this.left -= 1;
if (Math.abs(this.left) > this.scrollItemWidth) {
this.left = 0;
}
this.textScrollDiv.style.transform = `translate(${this.left}px, 0px)`;
}
},
// 鼠标划入区域
inBox() {
if (this.isScroll) {
clearInterval(this.timer);
this.timer = null;
}
},
// 鼠标离开区域
leaveBox() {
if (this.isScroll) {
const that = this;
this.timer = setInterval(function() {
that.moveLeft();
}, 30);
}
}
}
};
</script>
<style lang="less" scoped>
.text-scroll {
display: flex;
flex-wrap: nowrap;
transition: all 0ms ease-in 0s;
.scroll-item {
display: flex;
flex-wrap: nowrap;
}
}
</style>
外部引用
<template>
<!-- 公告信息板块 -->
<div v-if="noticeInfo && noticeInfo.length > 0" class="notice-plate">
<div class="plate-body">
<div class="plate-icon">
<i class="sxqyjj-iconfont sxqyjj-xiaoxi1"></i>
</div>
<div class="plate-info" @click="handleInfo($event)">
<textScroll>
<div
v-for="(item, i) in noticeInfo"
:key="'notice' + i"
class="info-item"
:data-my-id="item.id"
>
{{ item.title }}
<div v-if="i < noticeInfo.length - 1" class="line-split"></div>
</div>
</textScroll>
</div>
<div class="plate-more" @click="moreInfo">
更多
<i class="sxqyjj-iconfont sxqyjj-chevron-right"></i>
</div>
</div>
</div>
</template>
<script>
import textScroll from '@packages/views/components/text-scroll/index.vue';
export default {
name: 'Index',
components: {
textScroll
},
data() {
return {
noticeInfo: [],
};
},
created() {
this.getLastThreeConsultation();
},
methods: {
// 获取重点资讯
getLastThreeConsultation() {
this.$api['search/getLastThreeConsultation']()
.then(res => {
if (res.code === this.$constant.apiServeCode.SUCCESS_CODE) {
this.noticeInfo = res.data || [];
}
return true;
})
.catch(err => {
console.log(err);
});
}
}
}
};
</script>
<style lang="less" scoped>
/* stylelint-disable */
.notice-plate {
width: 1328px;
margin: 0 auto;
margin-top: 24px;
.plate-body {
display: flex;
align-items: flex-start;
width: 100%;
height: 48px;
padding: 10px 16px;
margin-left: -64px;
background: white;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 4px 4px 4px 4px;
.plate-icon {
width: 28px;
height: 28px;
margin-right: 16px;
line-height: 28px;
color: rgba(255, 143, 31, 1);
text-align: center;
background: rgb(255, 247, 241);
border-radius: 4px 4px 4px 4px;
}
.plate-info {
width: calc(100% - 112px);
height: 28px;
overflow: hidden;
line-height: 28px;
.info-item {
position: relative;
margin-right: 32px;
font-weight: 500;
white-space: nowrap;
&:hover {
color: rgba(0, 128, 255, 1);
cursor: pointer;
}
}
.line-split {
position: absolute;
top: 6px;
right: -16px;
width: 2px;
height: 12px;
border-right: 1px solid rgba(217, 217, 217, 1);
}
}
.plate-more {
height: 28px;
margin-left: 16px;
font-size: 14px;
line-height: 28px;
color: @text-2;
cursor: pointer;
i {
margin-left: 4px;
}
}
}
}
</style>