基于Vue2+ElementUI/Vue3+ElementPlus对el-notification增加倒计时进度条特效,鼠标移入,暂停计时,鼠标移出,继续计时
遇到一个需求就是对这个 el-notification 加一个倒计时进度条,方便用户知道该通知何时自动关闭。
一、示例代码
(1)基于Vue2+ElementUI的项目
<template>
<div>
<el-button @click="showTip">do it</el-button>
</div>
</template>
<script>
export default {
data: () => ({
classNameObj:{},
}),
created() {
console.log('created =>', 'SUCCESS')
// 在 created 生命周期,调用 method 的 yyyyyy 方法
// this.yyyyyy();
},
methods: {
/**
* 通知消息
*/
showTip() {
const h = this.$createElement;
const contents = []
const msg = h('p', {}, '任务启动成功!')
const task = h('p', {}, '任务ID:' + 1234)
const job = h('p', {}, 'JobID:' + 661234)
// 按钮事件
const readInfoNoticeButton = h('el-button', {
props: {
type:'primary',
size:"mini"
},
on: {
//为按钮绑定点击事件
click: () => {
this.readInfoNotice(notice_id,notifyInstance);
}
},
style: {
border: "none",
textAlign: "center",
marginTop: "2%",
marginLeft: "5%",
}
}, '标记已读');
const progress = h(
'div',
{
class: {
'el-progress-plus': true
},
style: {
'width': '230px',
'height': '6px',
'background-color': '#5e7ce0',
'margin-top': '6px',
'border-radius': '6px',
},
percentage: 100
},
''
)
const br = h('p', { style: 'width: auto; height: 10px' }, '')
contents.push(msg)
contents.push(task)
contents.push(job)
contents.push(progress)
contents.push(br)
let classID = 1
let className = 'el-notification-plus' + classID
// 判断是否已存在该通知元素,以及最多限制生成10000个通知
while(document.getElementsByClassName(className)[0]) {
if (classID > 10000) {
// 无法生成元素
console.log('无法生成元素')
break
} else {
// 继续累加
classID++
className = 'el-notification-plus' + classID
}
}
// 实例化通知
const notifyInstance = this.$notify({
title: '一键测试',
type: 'success',
customClass: className,
message: h('div', {}, contents),
duration: 0
})
// 启动倒计时
let timer = this.countDown(className, notifyInstance , 100) // 这里做了修改,默认传100,因为再倒计时方法获取不到定义的percentage为100的属性
// 获取 Notification 的DOM元素
const ElNotificationPlus = document.getElementsByClassName(className)[0]
// console.log('ElNotificationPlus =>', ElNotificationPlus)
// 为 Notification 元素 定义鼠标进入方法,暂停倒计时
ElNotificationPlus.onmouseenter = () => {
console.log('onmouseover~', className)
clearInterval(timer)
}
// 为 Notification 元素 定义鼠标移出方法,继续倒计时
ElNotificationPlus.onmouseleave = () => {
console.log('onmouseout~', className)
clearInterval(timer)
timer = this.countDown(className, notifyInstance,this.classNameObj[className])
}
},
// 按钮事件
readInfoNotice(notice_id,notifyInstance) {
// 手动关闭通知
setTimeout(() => {
notifyInstance.close()
}, 50);
// 标记为已读 调用的接口做一些处理
updReadNotice(notice_id).then(response => {
if (response.code && response.code === 200) {
this.msgSuccess(response.msg);
} else {
this.msgError("操作失败");
}
});
},
/**
* 倒计时
*/
countDown(className, notifyInstance,countdown) { //增加了当前属性的传参countdown
const timer = setInterval(() => {
try {
if (notifyInstance) {
const ElNotificationPlus = document.getElementsByClassName(className)[0]
// console.log('ElNotificationPlus =>', ElNotificationPlus)
const ElProgressPlus = ElNotificationPlus.getElementsByClassName('el-progress-plus')[0]
// console.log('ElProgressPlus =>', ElProgressPlus)
let percentage = ElProgressPlus.getAttribute('percentage')||countdown // 获取不到的时候就取传参的值
this.classNameObj[className] = percentage
if (percentage >= 0) {
percentage = percentage - 0.5
ElProgressPlus.setAttribute('percentage', percentage)
ElProgressPlus.style.width = (230 * (percentage / 100)) + 'px'
} else {
// 清除定时器
clearInterval(timer)
delete this.classNameObj[className] // 为0 或关闭时则清空该字段
// 手动关闭通知
setTimeout(() => {
notifyInstance.close()
}, 50);
}
} else {
// 清除定时器
clearInterval(timer)
delete this.classNameObj[className] // 为0 或关闭时则清空该字段
}
} catch (error) {
// 清除定时器
clearInterval(timer)
delete this.classNameObj[className] // 为0 或关闭时则清空该字段
}
}, 50)
return timer
},
}
}
</script>
<style>
.el-notification-plus .el-progress .el-progress__text{
display: none;
}
</style>
(2)基于Vue3+ElementPlus的项目
<template>
<div>
<el-button @click="showTip">do it</el-button>
</div>
</template>
<script>
import { h, onMounted, getCurrentInstance } from 'vue'
export default {
setup() {
onMounted(() => {
console.log('onMounted =>', 'SUCCESS')
// const { proxy } = getCurrentInstance()
// 在 onMounted 生命周期,调用 method 的 xxxxxx 方法
// proxy.xxxxxx()
})
},
data: () => ({
}),
created() {
console.log('created =>', 'SUCCESS')
// 在 created 生命周期,调用 method 的 yyyyyy 方法
// this.yyyyyy();
},
methods: {
/**
* 通知消息
*/
showTip() {
const contents = []
const msg = h('p', {}, '任务启动成功!')
const task = h('p', {}, '任务ID:' + 1234)
const job = h('p', {}, 'JobID:' + 661234)
const progress = h(
'div',
{
class: {
'el-progress-plus': true
},
style: {
'width': '230px',
'height': '6px',
'background-color': '#5e7ce0',
'margin-top': '6px',
'border-radius': '6px',
},
percentage: 100
},
''
)
const br = h('p', { style: 'width: auto; height: 10px' }, '')
contents.push(msg)
contents.push(task)
contents.push(job)
contents.push(progress)
contents.push(br)
let classID = 1
let className = 'el-notification-plus' + classID
// 判断是否已存在该通知元素,以及最多限制生成100个通知
while(document.getElementsByClassName(className)[0]) {
if (classID > 100) {
// 无法生成元素
console.log('无法生成元素')
break
} else {
// 继续累加
classID++
className = 'el-notification-plus' + classID
}
}
// 实例化通知
const notifyInstance = this.$notify({
title: '一键测试',
type: 'success',
customClass: className,
message: h('div', {}, contents),
duration: 0
})
// 启动倒计时
let timer = this.countDown(className, notifyInstance)
// 获取 Notification 的DOM元素
const ElNotificationPlus = document.getElementsByClassName(className)[0]
// console.log('ElNotificationPlus =>', ElNotificationPlus)
// 为 Notification 元素 定义鼠标进入方法,暂停倒计时
ElNotificationPlus.onmouseenter = () => {
console.log('onmouseover~', className)
clearInterval(timer)
}
// 为 Notification 元素 定义鼠标移出方法,继续倒计时
ElNotificationPlus.onmouseleave = () => {
console.log('onmouseout~', className)
clearInterval(timer)
timer = this.countDown(className, notifyInstance)
}
},
/**
* 倒计时
*/
countDown(className, notifyInstance) {
const timer = setInterval(() => {
try {
if (notifyInstance) {
const ElNotificationPlus = document.getElementsByClassName(className)[0]
// console.log('ElNotificationPlus =>', ElNotificationPlus)
const ElProgressPlus = ElNotificationPlus.getElementsByClassName('el-progress-plus')[0]
// console.log('ElProgressPlus =>', ElProgressPlus)
let percentage = ElProgressPlus.getAttribute('percentage')
if (percentage >= 0) {
percentage = percentage - 0.5
ElProgressPlus.setAttribute('percentage', percentage)
ElProgressPlus.style.width = (230 * (percentage / 100)) + 'px'
} else {
// 清除定时器
clearInterval(timer)
// 手动关闭通知
setTimeout(() => {
notifyInstance.close()
}, 50);
}
} else {
// 清除定时器
clearInterval(timer)
}
} catch (error) {
// 清除定时器
clearInterval(timer)
}
}, 50)
return timer
},
}
}
</script>
<style>
.el-notification-plus .el-progress .el-progress__text{
display: none;
}
</style>