👉 前言
在 Vue + elementUi 开发中,遇到这么一个需求,要实现公告轮播的效果。说实话,一开始是打算通过Javascript去获取并修改对应元素来控制轮播的,但是发现这样子代码比较多,而且性能不是很好。
然后...聪明的小温想到了,能不能通过vue的动画过渡,实现公告的滚动效果呢! 一不做二不休,直接上手,果然是可以实现的!
接下来,简单阐述下,开发中使用方法!
tips
:
vue动画过渡 - Transition 官方文档
👉 一、效果演示
话不多说,先上效果图! 白嫖万岁!当然,如果有帮助,希望不要吝啬你的点赞呀!
👉 二、实现思路
通过对一个index
进行公告显示条数进行记录,然后通过定时器
定时显示/关闭,实现对应元素的动画入场和出场动画效果!
借助elementUI
中的popover组件,利用show
、hide
方法,实现鼠标悬浮暂停轮播功能,鼠标移出继续轮播!
直接看代码吧! 简单易懂!
由于案例中,公告内容是富文本,所以说,本文用了之前提到的富文本组件,混杂了富文本回显的,大伙可以直接忽略即可!
👉 三、实现案例
> HTML模板
<template>
<span class="carousel">
<template v-if="announcementList.length !== 0">
<Transition name="slide-fade">
<el-popover
placement="bottom"
trigger="hover"
v-show="announcemenShow"
@show="announcemenClose"
@hide="announcemenOpen"
>
<p
style="
min-width: 200px;
max-width: 30vw;
max-height: 25vh;
overflow-y: auto;
"
v-html="announcementList[announcemenIndex].label"
class="el-tiptap-editor__content"
></p>
<div style="text-align: right;">
<el-button
type="text"
style="font-weight: bold; padding: 2px 0;"
@click="goAnnouncemen"
>查看详情</el-button>
</div>
<el-tag
slot="reference"
effect="dark"
style="cursor: pointer;"
:type="tagType[announcementList[announcemenIndex].type] || ''"
@click="goAnnouncemen"
>
<i class="el-icon-message" style="padding-right: 5px;" > {{ announcementList[announcemenIndex].type }} :</i>
{{ deleteHtml(announcementList[announcemenIndex].label) }}
</el-tag>
</el-popover>
</Transition>
</template>
<el-tag v-else type="info">暂无公告</el-tag>
</span>
</template>
> Js模板
let Data = {
announcemenTimer: null,
announcemenShow: true,
announcemenIndex: 0,
announcementList: [
{
label: '本系统由于技术原因,将于2023年4月25日 16:00开始系统更新,预计花费2小时。将于当天18:00完成本次更新!',
type: '更新公告'
},
{
label: '风控中心,监测模块问题维护',
type: '紧急维护'
},
{
label: '数据错位',
type: '重要通知'
},
{
label: '测试444',
type: '其他'
},
{
label: '测试555',
type: '其他'
},
],
// 对应显示tag样式
tagType: {
'更新公告': '',
'紧急维护': 'danger',
'重要通知': 'warning',
'其他': 'info',
},
}
created() {
this.announcemenOpen()
},
watch: {
announcementList() {
this.announcemenOpen()
},
},
//页面销毁时清除定时器
beforeDestroy() {
clearInterval(this.announcemenTimer);
},
menthods: {
// 开启公告轮播
announcemenOpen() {
if(this.announcementList.length <= 1) {
return
}
// 防抖节流
this.announcemenTimer &&
(() => {
clearInterval(this.announcemenTimer);
this.announcemenTimer = null;
})();
this.announcemenTimer = setInterval(() => {
this.announcemenShow = false
// window.console.log(this.announcemenIndex)
setTimeout(() => {
if(this.announcemenIndex < this.announcementList.length - 1) {
this.announcemenIndex++
} else {
this.announcemenIndex = 0
}
this.announcemenShow = true
}, 500) // 过渡动画衔接时间,和过渡动画样式对应,需要错开一点时间,视觉上看起来更流畅一点
}, 5000) // 轮播信息滞留时间
},
// 关闭公告轮播
announcemenClose() {
clearInterval(this.announcemenTimer);
},
// 跳转公告页面
goAnnouncemen() {
if(this.$route.path == '/announcements') {
this.$message.info('您已在公告页面,请查看公告!')
return
}
this.$router.push({
path: "/announcements",
query: {
actNav: 6,
index: '6-3'
},
});
},
}
> CSS 模板
// 动画样式
<style>
.slide-fade-enter-active {
animation: slide-fade-in 0.8s;
}
.slide-fade-leave-active {
animation: slide-fade-out 0.6s;
}
@keyframes slide-fade-out {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-240px);
opacity: 0;
}
}
@keyframes slide-fade-in {
0% {
transform: translateX(240px);
opacity: 0;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
</style>
// 页面样式
<style scoped lang="scss">
.carousel {
width: 300px;
color: #fff;
margin-right: 15px;
overflow: hidden;
display: flex;
align-items: center;
/deep/ {
.el-popover__reference-wrapper {
display: flex;
align-items: center;
}
.el-tag {
width: 280px;
margin: 0 10px;
border-radius: 3px;
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
</style>
案例较为粗浅,仅供参考!