项目中使用 element-ui 时, message 弹框功能是必须使用的, 有时会在点击按钮时提示无权限, 或者请求报错时给出适当提示:
但是重复点击按钮或者同一个页面多个请求同时报错时, 就不美观了
可以看到, element-ui 是动态往页面根节点插入 message 元素来实现弹框效果的, 都拥有 el-message 属性
那么我们就可以通过判断页面中 message 的个数来决定要不要弹出第二个提示框
这就需要重新写一下 element-ui 的 message
resetMessage.JS
- /** 重置 message, 防止重复点击重复弹出 message 弹框 */
- import {
- Message
- } from 'element-ui';
- const showMessage = Symbol('showMessage')
- class DoneMessage {
- [showMessage](type, options, single) {
- if (single) {
- if (document.getElementsByClassName('el-message').length === 0) {
- Message[type](options)
- }
- } else {
- Message[type](options)
- }
- }
- info(options, single = true) {
- this[showMessage]('info', options, single)
- }
- warning(options, single = true) {
- this[showMessage]('warning', options, single)
- }
- error(options, single = true) {
- this[showMessage]('error', options, single)
- }
- success(options, single = true) {
- this[showMessage]('success', options, single)
- }
- }
- export const message = new DoneMessage();
main.JS 引入
import { message } from '@/utils/resetMessage'; ,,,, vue.use(ElementUI) Vue.prototype.$message = message;
全局调用方法:
this.$message.error('hello') 或者 this,$message.error({message:'hello'})
注意: 挂载自定义 message 必须放在 Vue.use(ElementUI) 后面, 才能覆盖 element-ui 默认的 message, 不然没有效果
这样就不用担心重复点击会弹出好多弹框了
============================================================
今天同事提出了个获取更好体验的方法
按先前的方法, 是更具页面中 el-message 的数量来决定要不要弹出下一个提示框, 重复点击按钮时必须等上一个 message 隐藏了之后才能弹下一个, 这就导致后续的点击没有反应, 缺少页面反馈, 会有卡顿的错觉, 如果快速点击不同提示的按钮, 由于第一个弹框还没隐藏, 后续不同的提示也不会展示.
此时点击第二个按钮, 但提示依然是按钮 1 的提示语
解决:
利用 element-ui 中 message 的 close 方法, 在下一个弹框弹出前先把上一个弹框实例关闭掉
把之前的代码改造一下:
/** 重置 message, 防止重复点击重复弹出 message 弹框 */ import { Message } from 'element-ui'; const showMessage = Symbol('showMessage'); let messageInstance = null; class DoneMessage { [showMessage](type, options, single) { if (messageInstance && single) { messageInstance.close() } messageInstance = Message[type](options) // if (single) { // if (document.getElementsByClassName('el-message').length === 0) { // Message[type](options) // } // } else { // Message[type](options) // } } info(options, single = true) { this[showMessage]('info', options, single) } warning(options, single = true) { this[showMessage]('warning', options, single) } error(options, single = true) { this[showMessage]('error', options, single) } success(options, single = true) { this[showMessage]('success', options, single) } } export const message = new DoneMessage();
这样重复点击的时候页面弹框和用户的行为有了一定的交互, 体验更好
==========================================================
2019-12-31 编辑
这样的封装方法有一个缺陷, 因为是通过 new 方法创建的对象, 所以只能拿通过 $message.error() 的形式调用, 不支持 $message({}) 形式调用, 参考 element-ui 中 message 方法的实现, 将封装再次优化一下
resetMessage.JS
/** 重置 message, 防止重复点击重复弹出 message 弹框 */ import { Message } from 'element-ui'; let messageInstance = null; const resetMessage = (options) => { if(messageInstance) { messageInstance.close() } messageInstance = Message(options) } ;['error','success','info','warning'].forEach(type => { resetMessage[type] = options => { if(typeof options === 'string') { options = { message:options } } options.type = type return resetMessage(options) } }) export const message = resetMessage
这样两种调用方式都支持了
来源: https://blog.csdn.net/dongguan_123/article/details/101290164