vue實(shí)現(xiàn)消息列表向上無縫滾動(dòng)效果
一、背景
最近產(chǎn)品有個(gè)需求:后臺(tái)系統(tǒng)的未讀消息,在用戶登陸后,將未讀信息在右側(cè)浮窗無縫滾動(dòng);不關(guān)閉時(shí),間隔10秒逐級(jí)消失逐級(jí)上浮,每次只展示一條消息;支持手動(dòng)關(guān)閉浮窗;支持單擊浮窗打開相應(yīng)消息。
二、需要實(shí)現(xiàn)的效果

三、實(shí)現(xiàn)思路
根據(jù)需求,準(zhǔn)備采用CSS(transition)結(jié)合JS(setTimeout)的方案進(jìn)行實(shí)現(xiàn),因?yàn)楣δ鼙容^簡單,所以沒有使用第三方插件,也方便自定義樣式。
四、實(shí)現(xiàn)方法
- 首先我們先實(shí)現(xiàn)樣式,看下
html的實(shí)現(xiàn)代碼:

代碼如下圖:
<template>
<div :class="{anim:animate}" @mouseenter="stop()" @mouseleave="up()" class="unreadMsg">
<div class="news_name" v-for="(item, index) in newsList" :key="item.id" @click="handleDetail(item)">
<div class="content">
<div class="title">{{ item.title }}</div>
<div class="des">{{ item.description }}</div>
</div>
<span @click="handleDelete(item, index)" class="close">
<a-icon type="close" style="cursor: pointer" />
</span>
</div>
</div>
</template>
注:我的項(xiàng)目是
ant-vue框架,上面代碼中用到一個(gè)關(guān)閉icon(a-icon)標(biāo)簽,可作替換。
- 接下來是
css的實(shí)現(xiàn)代碼:
<style lang="less" scoped>
.unreadMsg {
max-height: 132px;
overflow: hidden;
position: absolute;
right: 0;
top: 0;
bottom: auto;
margin-inline-end: 24px;
.news_name {
line-height: 30px;
transition: top 0.5s;
transition-delay: 10s;
position: relative;
.content {
position: relative;
width: 384px;
margin-bottom: 40px;
margin-inline-start: auto;
padding: 20px 30px;
overflow: hidden;
word-wrap: break-word;
background: #fff;
border-radius: 8px;
.title {
padding-right: 12px;
margin-bottom: 8px;
color: rgba(0, 0, 0, 0.88);
font-size: 16px;
line-height: 1.5;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.des {
font-size: 14px;
cursor: pointer;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
}
.close {
position: absolute;
top: 20px;
inset-inline-end: 24px;
color: rgba(0, 0, 0, 0.45);
outline: none;
width: 22px;
height: 22px;
border-radius: 4px;
transition: background-color 0.2s, color 0.2s;
display: flex;
align-items: center;
justify-content: center;
}
}
}
.anim {
transition: all 0.5s;
margin-top: -110px;
}
</style>
- 最后通過
js實(shí)現(xiàn)各項(xiàng)功能:
- 首先實(shí)現(xiàn) 每條消息間隔10秒逐級(jí)消失逐級(jí)上浮 功能:
// 滾動(dòng)動(dòng)畫
scrollUp() {
// 每個(gè)消息展示10s
this.timer = setInterval(() => {
this.animate = true // 向上滾動(dòng)的時(shí)候需要添加動(dòng)畫
setTimeout(() => {
this.newsList.push(this.newsList[0])// 將數(shù)組的第一個(gè)元素添加到數(shù)組最后一個(gè)
this.newsList.shift() // 刪除數(shù)組的第一個(gè)元素
this.animate = false
}, 500)
}, 10000)
},
需要注意到是,這個(gè)滾動(dòng)動(dòng)畫的方法,需要在mounted生命周期中執(zhí)行,在created生命周期中請(qǐng)求后端接口,獲取未讀消息的list數(shù)組。
另:此處的10s可根據(jù)自己項(xiàng)目需求進(jìn)行調(diào)整。
- 實(shí)現(xiàn) 單擊浮窗打開相應(yīng)消息 功能:
handleDetail(item) {
this.$router.push({ name: 'noticeDetailService', params: { id: item.id } })
},
這里只要點(diǎn)擊對(duì)應(yīng)的消息,跳轉(zhuǎn)到這個(gè)消息具體的詳情頁即可。因?yàn)槊總€(gè)消息都會(huì)有自己對(duì)應(yīng)的ID,不用多說,都懂。
- 實(shí)現(xiàn) 手動(dòng)關(guān)閉當(dāng)前的消息 功能:
handleDelete(item, index) {
this.newsList.splice(index, 1) // 刪除數(shù)組的當(dāng)前元素
},
此處主要考慮的問題是,有的消息用戶不想點(diǎn)開看詳情,也不想看它在輪播,想直接關(guān)掉。只需要?jiǎng)h除數(shù)組中的當(dāng)前元素即可。
最后記得在
beforeDestroy生命周期中清除計(jì)時(shí)器clearInterval。下面將
js的全部代碼附上:

<script>
import { noticeSearch } from '../api/index.js'
export default {
name: 'unreadMsg',
data() {
return {
timer: null,
animate: false,
newsList: []
}
},
created() {
this.noticeSearch()
},
mounted() {
this.scrollUp() // 開啟滾動(dòng)效果
},
beforeDestroy() {
this.stop()
},
methods: {
async noticeSearch () {
const data = await noticeSearch({ size: -1 })
this.newsList = data.list
},
// 查看公告詳情
handleDetail(item) {
this.$router.push({ name: 'noticeDetailService', params: { id: item.id } })
},
handleDelete(item, index) {
this.newsList.splice(index, 1) // 刪除數(shù)組的當(dāng)前元素
},
// 滾動(dòng)動(dòng)畫
scrollUp() {
// 每個(gè)消息展示10s
this.timer = setInterval(() => {
this.animate = true // 向上滾動(dòng)的時(shí)候需要添加動(dòng)畫
setTimeout(() => {
this.newsList.push(this.newsList[0])// 將數(shù)組的第一個(gè)元素添加到數(shù)組最后一個(gè)
this.newsList.shift() // 刪除數(shù)組的第一個(gè)元素
this.animate = false
}, 500)
}, 10000)
},
// 鼠標(biāo)移上去停止
stop() {
clearInterval(this.timer)
},
// 鼠標(biāo)離開繼續(xù)
up() {
this.scrollUp()
}
}
}
</script>
五、總結(jié)
功能雖簡單,需要注意的點(diǎn)也很多,要記得在對(duì)應(yīng)的生命周期做對(duì)應(yīng)的操作。用到定時(shí)器的地方也要記得進(jìn)行清除。
以上就是vue實(shí)現(xiàn)消息列表向上無縫滾動(dòng)的詳細(xì)內(nèi)容,更多關(guān)于vue列表滾動(dòng)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
element表單驗(yàn)證如何清除校驗(yàn)提示語
本文主要介紹了element表單驗(yàn)證如何清除校驗(yàn)提示語,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
Vue?Mock.js介紹和使用與首頁導(dǎo)航欄左側(cè)菜單搭建過程
Mock.js是一個(gè)模擬數(shù)據(jù)的生成器,用來幫助前端調(diào)試開發(fā)、進(jìn)行前后端的原型分離以及用來提高自動(dòng)化測(cè)試效率,這篇文章主要介紹了Vue?Mock.js介紹和使用與首頁導(dǎo)航欄左側(cè)菜單搭建,需要的朋友可以參考下2023-09-09
詳解vue前后臺(tái)數(shù)據(jù)交互vue-resource文檔
本篇文章主要介紹了vue前后臺(tái)數(shù)據(jù)交互vue-resource文檔,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
關(guān)于vue 的slot分發(fā)內(nèi)容 (多個(gè)分發(fā))
這篇文章主要介紹了關(guān)于vue 的slot分發(fā)內(nèi)容 (多個(gè)分發(fā)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
如何在Vue項(xiàng)目中應(yīng)用TypeScript類
與如何在React項(xiàng)目中應(yīng)用TypeScript類類似在VUE項(xiàng)目中應(yīng)用typescript,我們需要引入一個(gè)庫vue-property-decorator,需要的小伙伴可續(xù)看下文具體介紹2021-09-09
vue+echarts實(shí)現(xiàn)動(dòng)態(tài)繪制圖表及異步加載數(shù)據(jù)的方法
vue寫的后臺(tái)管理,需要將表格數(shù)據(jù)繪制成圖表(折線圖,柱狀圖),圖表數(shù)據(jù)都是通過接口請(qǐng)求回來的。這篇文章主要介紹了vue+echarts 動(dòng)態(tài)繪制圖表及異步加載數(shù)據(jù)的相關(guān)知識(shí),需要的朋友可以參考下2018-10-10
vue執(zhí)行配置選項(xiàng)npm?run?serve的本質(zhì)圖文詳解
本地開發(fā)一般通過執(zhí)行npm run serve命令來啟動(dòng)項(xiàng)目,那這行命令到底存在什么魔法?下面這篇文章主要給大家介紹了關(guān)于vue執(zhí)行配置選項(xiàng)npm?run?serve的本質(zhì)的相關(guān)資料,需要的朋友可以參考下2023-05-05

