前言
本文主要实现vue项目中,消息列表逐条向上无缝滚动,每条消息展示10秒后再滚动,为了保证用户能看清消息主题。未使用第三方插件。本文实现方法比较简约。可复制粘贴直接用哦~
一、背景最近产品有个需求:后台系统的未读消息,在用户登陆后,将未读信息在右侧浮窗无缝滚动;不关闭时,间隔10秒逐级消失逐级上浮,每次只展示一条消息;支持手动关闭浮窗;支持单击浮窗打开相应消息。
二、需要实现的效果三、实现思路根据需求,准备采用CSS(transition)结合JS(setTimeout)的方案进行实现,因为功能比较简单,所以没有使用第三方插件,也方便自定义样式。
四、实现方法首先我们先实现样式,看下html的实现代码:代码如下图:
<template> <div :class="{anim:animate}" @mouseenter="stop()" @mouseleave="up()">注:我的项目是ant-vue框架,上面代码中用到一个关闭icon(a-icon)标签,可作替换。
接下来是css的实现代码:<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实现各项功能:首先实现 每条消息间隔10秒逐级消失逐级上浮 功能:// 滚动动画scrollUp() { // 每个消息展示10s this.timer = setInterval(() => { this.animate = true // 向上滚动的时候需要添加动画 setTimeout(() => { this.newsList.push(this.newsList[0])// 将数组的第一个元素添加到数组最后一个 this.newsList.shift() // 删除数组的第一个元素 this.animate = false }, 500) }, 10000)},需要注意到是,这个滚动动画的方法,需要在mounted生命周期中执行,在created生命周期中请求后端接口,获取未读消息的list数组。另:此处的10s可根据自己项目需求进行调整。
实现 单击浮窗打开相应消息 功能:handleDetail(item) { this.$router.push({ name: 'noticeDetailService', params: { id: item.id } }) },这里只要点击对应的消息,跳转到这个消息具体的详情页即可。因为每个消息都会有自己对应的ID,不用多说,都懂。
实现 手动关闭当前的消息 功能:handleDelete(item, index) { this.newsList.splice(index, 1) // 删除数组的当前元素},此处主要考虑的问题是,有的消息用户不想点开看详情,也不想看它在轮播,想直接关掉。只需要删除数组中的当前元素即可。
最后记得在beforeDestroy生命周期中清除计时器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() // 开启滚动效果 }, 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) // 删除数组的当前元素 }, // 滚动动画 scrollUp() { // 每个消息展示10s this.timer = setInterval(() => { this.animate = true // 向上滚动的时候需要添加动画 setTimeout(() => { this.newsList.push(this.newsList[0])// 将数组的第一个元素添加到数组最后一个 this.newsList.shift() // 删除数组的第一个元素 this.animate = false }, 500) }, 10000) }, // 鼠标移上去停止 stop() { clearInterval(this.timer) }, // 鼠标离开继续 up() { this.scrollUp() } }}</script>五、总结功能虽简单,需要注意的点也很多,要记得在对应的生命周期做对应的操作。用到定时器的地方也要记得进行清除。
作者:小蹦跶儿链接:https://juejin.cn/post/7374965362196398132