记一次开发任务
需求:
多次点击导致$message 加载过多(满屏),要求仅加载一次,并且出现重复提示时抖动
实际开发中发现其实多了一个要求:抖动后时间重置的问题
大致实现思路:

重新拦截一下Message,所有的$message都走封装好的方法
关闭、清除计时器、重置时间方法在下图

// 仅个人开发记录,若有更多好的方法欢迎分享
import { Message } from 'element-ui'
import { cloneDeep, isEqual } from 'lodash'
let messageInstance = null
let cloneOptions = {}
const resetMesage = option => {
const options = {
offset: 50,
...option,
}
const { type, message } = options
// 用来作比较
const compareMessage = { type, message }
const messageDom = document.getElementsByClassName('el-message')[0]
if (messageDom === undefined) {
messageInstance = Message(options)
console.log(messageInstance)
} else if (
messageDom !== undefined &&
!isEqual(compareMessage, cloneOptions)
) {
// 类型不一致关闭上一个实例,再次创建实例
messageInstance.close()
messageInstance = Message(options)
} else if (
messageDom !== undefined &&
isEqual(compareMessage, cloneOptions)
) {
// 类型一致抖动,重置展示时间
messageDom.classList.add('message-shaking')
messageInstance.clearTimer()
messageInstance.startTimer()
// 新增动画
const timer = setTimeout(() => {
messageDom.classList.remove('message-shaking')
clearTimeout(timer)
}, 150)
}
cloneOptions = cloneDeep(compareMessage)
}
// 重新设置message的类型方法
;['success', 'warning', 'info', 'error'].forEach(type => {
resetMesage[type] = function (option) {
let options = option || {}
if (typeof option === 'string') {
options = {
message: option,
}
}
options.type = type
return resetMesage(options)
}
})
const message = resetMesage
export default message
使用方法与element-ui使用方法一致
main.js 文件
因为几乎都是全局在用,所以直接挂载在Vue.prototype 上
Vue.prototype.$message = message 一定要写在 Vue.use(ElementUI) 下边,否则无效,代码先后顺序问题
import message from '@/utils/resetMessage.js'
Vue.use(ElementUI)
Vue.prototype.$message = message
也可以局部使用
import singleMessage from '@/utils/resetMessage.js'
//
singleMessage.error('message')
// 或者
singleMessage({
type: 'error',
message: '123123'
})
抖动动画css,在element-ui位移原基础上加的抖动
.message-shaking {
animation: shaking 0.15s 4 linear;
}
@keyframes shaking {
0% {
transform: translate(calc(-50% - 1px), -1px);
}
20% {
transform: translate(-50%, 0);
}
40% {
transform: translate(calc(-50% + 1px), 1px);
}
60% {
transform: translate(calc(-50%), 0);
}
80% {
transform: translate(calc(-50% + 1px), 1px);
}
100% {
transform: translate(calc(-50% - 1px), -1px);
}
}