1 解决由于MessageBox打开后按钮自动聚焦导致的按钮处于active状态问题
element-ui提供的MessageBox有一个细节问题,当MessageBox打开后确定按钮会有一个自动聚焦的效果,导致组件渲染完成后确认按钮处于active状态,需要点击旁处使确认按钮失去焦点才能恢复正常的样式,效果如下:
为了解决此问题,可以在MessageBox打开前设置一个1ms的延时,使遮罩层获取焦点:
open() {
setTimeout(() => {
document.querySelector('.el-message-box__wrapper').focus()
}, 1)
this.$confirm('此操作将永久删除该文件, 是否继续?', {
title: '提示',
confirmButtonText: '确定',
cancelButtonText: '取消',
dangerouslyUseHTMLString: true,
closeOnClickModal: false
}).then(() => {
}).catch(() => {
})
}
虽然采用延时器的方法解决此问题比较low,但是目前我还没有想到第二种方法,欢迎大家集思广益。
2 调换MessageBox取消按钮和确定按钮的位置
element-ui提供的MessageBox默认的按钮样式是取消在前,确定在后:
若需求是确定在前,取消在后,那么可以通过下面的方法调换取消按钮和确定按钮的位置(messageTips是为了避免样式污染而通过customClass属性给MessageBox自定义的类名):
.messageTips .el-message-box__btns {
display: flex;
flex-direction: row-reverse;
gap: 10px;
}
3 自定义MessageBox标题前的icon图标
通过CSS定位将.el-message-box__content中的icon固定在.el-message-box__header的前面:
this.$confirm('<i class="iconfont icon-tips"></i>此操作将永久删除该文件, 是否继续?', {
title: '提示',
confirmButtonText: '确定',
cancelButtonText: '取消',
dangerouslyUseHTMLString: true,
customClass: 'messageTips'
}).then(() => {
}).catch(() => {
})
.icon-tips {
font-size: 25px !important;
color: orange;
position: absolute;
top: -40px;
}
.messageTips .el-message-box__header span {
margin-left: 30px;
}
4 实现MessageBox底部的checkbox功能
通过CSS定位将.el-message-box__content中的.Prompt固定在.el-message-box__btns的前面:
open() {
this.$confirm('<div class="Prompt"><input type="checkbox" id="Prompt-left"/><label for="Prompt-left"></label><span class="Prompt-right">不再提示</span></div>此操作将永久删除该文件, 是否继续?', {
title: '提示',
confirmButtonText: '确定',
cancelButtonText: '取消',
dangerouslyUseHTMLString: true,
customClass: 'messageTips'
}).then(() => {
}).catch(() => {
})
this.$nextTick(() => {
document.getElementById('Prompt-left').addEventListener('change', this.handleUserCheck)
})
},
handleUserCheck() {
console.log(document.getElementById('Prompt-left').checked)
}
.messageTips .el-message-box__content {
min-height: 68px;
}
.messageTips .Prompt {
font-size: 14px;
position: absolute;
bottom: -87px;
display: flex;
align-items: center;
}
.Prompt > input {
display: none;
}
.Prompt > label {
display: inline-block;
width: 14px;
height: 14px;
border-radius: 2px;
border: 1px solid #e4e7ed;
margin-right: 5px;
position: relative;
cursor: pointer;
}
.Prompt > label::before {
display: inline-block;
content: " ";
width: 8px;
border: 2px solid #fff;
height: 4px;
border-top: none;
border-right: none;
border-color: #409eff;
transform: rotate(-45deg);
top: 2px;
left: 2px;
position: absolute;
opacity: 0;
}
.Prompt > input:checked+label {
background-color: #fff;
border-color: #409eff;
}
.Prompt > input:checked+label::before {
opacity: 1;
transform: all 0.5s;
}
5 点击MessageBox遮罩层的抖动效果
通过beforeClose属性在关闭MessageBox前设置判断逻辑,但是注意配合distinguishCancelAndClose:true和closeOnClickModal:false才能生效:
this.$confirm('此操作将永久删除该文件, 是否继续?', {
title: '提示',
confirmButtonText: '确定',
cancelButtonText: '取消',
dangerouslyUseHTMLString: true,
distinguishCancelAndClose: true,
customClass: 'messageTips',
beforeClose: (action, instance, done) => {
const clickEvent = (event) => {
if (action === 'confirm' || action === 'cancel') {
done()
} else {
if (event.target.classList[0] === 'el-message-box__wrapper') {
const messageBox = document.querySelector('.messageTips')
messageBox.style.transform = 'scale(1.01)'
setTimeout(() => {
messageBox.style.transform = 'scale(1)'
}, 150)
} else if (event.target.classList[0] === 'el-message-box__close') {
done()
}
}
document.body.removeEventListener('click', clickEvent)
}
document.body.addEventListener('click', clickEvent)
}
}).then(() => {
}).catch(() => {
})