ElementUI之Message功能拓展详解


Posted in Javascript onOctober 18, 2019

在最近项目开发中,接口错误信息是在拦截器统一处理,在一次产品大大验收过程中,由于服务器没有重启完成,导致前端弹出一推错误提示语,产品大大对于提示语的交互效果提出了一系列的建议。由于项目使用了ElementUI框架,加上本人喜欢投(xin)机(shou)取(nian)巧(lai),于是去查看ElementUI Message的源码,根据实际需求自定义了Message功能。

场景描述

  • 场景一:限制页面同时展示消息提示语的最大数量(优先展示后插入的提示语)
  • 场景二:根据不同情况可以优先显示新/旧消息提示语
  • 场景三:如果超出了最大显示数量,则剩余的消息以队列的显示依次展示

实现方案

场景一

功能描述

  • 根据设置的最大数量,如果存储的实例列表instances长度超出最大限制数则销毁之前的消息实例instance(调用Message方法创建消息提示语会返回当前消息的一个实例),否则保存新建实例instance到实例列表instances中
  • 如果消息提示语消失,需要从实例列表instances中移除当前实例instance,确保页面显示消息数量与instances列表长度统一

代码实现

新建ZMessage构造函数import { Message } from 'element-ui'

function ZMessage (options) {
  if (!(this instanceof ZMessage)) {
    return new ZMessage(options)
  }
  this.init(options)
}

静态配置项和实例列表

ZMessage.config = {
 max: 0, // 最大显示数
}

 
ZMessage.instances = [] // 消息体实例列表

定义创建消息和监听实例消失事件方法

ZMessage.prototype.setMessage = function (options) {
 const instance = Message(options)
 // 监听消息消失事件,从实例列表移除当前消息实例
 instance.$watch('visible', val => {
  ZMessage.instances = ZMessage.instances.filter(item => item !== instance)
 })
 ZMessage.instances.push(instance)
}

定义移除消息实例方法

ZMessage.prototype.prototype.removeMessages = function () {
 const {
  instances,
  config: { max }
 } = ZMessage
 ZMessage.instances = instances.filter((instance, index) => {
  if (index < instances.length - max + 1) {
   instance && instance.close()
   return false
  }
  return true
 })
}

初始化消息

ZMessage.prototype.init = function (options) {
 const { max } = ZMessage.config
 // 判断如果超出最大消息数时,删除消息
 if (max > 0 && ZMessage.instances.length >= max) {
  this.removeMessages() :
 }
 if (ZMessage.instances.length < max || !max) {
  this.setMessage(options)
 }
}

场景二

功能描述

  • 在场景一的基础上新增优先取消息还是旧消息的标志操作

代码实现

静态配置项和实例列表

ZMessage.config = {
 max: 0, // 最大显示数
 showNewest: true // 是否后添加的消息覆盖前面的消息
}

初始化

ZMessage.prototype.init = function (options) {
 const { max, showNewest } = ZMessage.config
 // 判断如果超出最大消息数时,删除消息
 if (max > 0 && ZMessage.instances.length >= max && showNewest) {
  this.removeMessages()
 }
 if (ZMessage.instances.length < max || !max) {
  this.setMessage(options)
 }
}

场景三

功能描述

  • 在场景一场景二基础上添加是否使用队列方式存储未展示消息的实例,如果超出了最大限制数则创建消息实例的容器存储到消息队列queue中
  • 监听是否有消息消失,如果有则从消息队列queue中取出第一个容器,创建消息实例

代码实现

静态配置项和消息容器队列

ZMessage.config = {
 max: 0, // 最大显示数
 showNewest: true, // 是否后添加的消息覆盖前面的消息
 isQueue: false // 是否以队列形式存储为展示消息
}

ZMessage.queue = [] // 未展示数据的消息容器队列

生成队列

// 生成队列元素,延迟执行
ZMessage.prototype.saveToQueue = function (options) {
 return () => {
  this.setMessage(options)
 }
}

初始化

// 初始化
ZMessage.prototype.init = function (options) {
 const { max, isQueue, showNewest } = ZMessage.config
 // 判断如果超出最大消息数时,删除消息
 if (max > 0 && ZMessage.instances.length >= max && showNewest && !isQueue) {
  this.removeMessages()
 }

 if (ZMessage.instances.length >= max && isQueue) {
  // 添加队列元素
  ZMessage.queue.push(this.saveToQueue(options))
 } else if (ZMessage.instances.length < max || !max) {
  this.setMessage(options)
 }
}

获取消息实例和添加事件监听

// 获取消息实例和添加事件监听
ZMessage.prototype.setMessage = function (options) {
 const instance = Message(options)
 // 监听消息消失事件,从实例列表移除当前消息实例
 instance.$watch('visible', val => {
  ZMessage.instances = ZMessage.instances.filter(item => item !== instance)
  if (ZMessage.config.isQueue && ZMessage.queue.length) {
   ZMessage.queue.shift()()
  }
 })
 ZMessage.instances.push(instance)
}

最后一步

添加不同消息类型功能静态方法

const messageTypes = ['success', 'warning', 'error', 'info']

// 各消息类型静态方法
messageTypes.forEach(type => {
 ZMessage[type] = options => {
  let opts = options
  if (typeof options === 'string') {
   opts = {
    message: options
   }
  }
  return new ZMessage({ ...opts, type })
 }
})

完整代码

// ZMessage.js
import { Message } from 'element-ui'

const messageTypes = ['success', 'warning', 'error', 'info']

function ZMessage (options) {
 if (!(this instanceof ZMessage)) {
  return new ZMessage(options)
 }
 this.init(options)
}

ZMessage.queue = [] // 未展示数据的消息队列

ZMessage.instances = [] // 消息体实例列表

// 配置项
ZMessage.config = {
 max: 0, // 最大显示数
 isQueue: false, // 是否以队列形式存储为展示消息
 showNewest: true // 是否后添加的消息覆盖前面的消息
}

// 配置参数
ZMessage.setConfig = function (config = {}) {
 ZMessage.config = { ...ZMessage.config, ...config }
}

ZMessage.close = Message.close

ZMessage.closeAll = Message.closeAll

// 各消息类型静态方法
messageTypes.forEach(type => {
 ZMessage[type] = options => {
  let opts = options
  if (typeof options === 'string') {
   opts = {
    message: options
   }
  }
  return new ZMessage({ ...opts, type })
 }
})

// 初始化
ZMessage.prototype.init = function (options) {
 const { max, isQueue, showNewest } = ZMessage.config
 // 判断如果超出最大消息数时,删除消息
 if (max > 0 && ZMessage.instances.length >= max && showNewest && !isQueue) {
  this.removeMessages()
 }

 if (ZMessage.instances.length >= max && isQueue) {
  // 添加队列元素
  ZMessage.queue.push(this.saveToQueue(options))
 } else if (ZMessage.instances.length < max || !max) {
  this.setMessage(options)
 }
}

// 移除消息
ZMessage.prototype.removeMessages = function () {
 const {
  instances,
  config: { max }
 } = ZMessage
 ZMessage.instances = instances.filter((instance, index) => {
  if (index < instances.length - max + 1) {
   instance && instance.close()
   return false
  }
  return true
 })
}

// 获取消息实例和添加事件监听
ZMessage.prototype.setMessage = function (options) {
 const instance = Message(options)
 // 监听消息消失事件,从实例列表移除当前消息实例
 instance.$watch('visible', val => {
  ZMessage.instances = ZMessage.instances.filter(item => item !== instance)
  if (ZMessage.config.isQueue && ZMessage.queue.length) {
   ZMessage.queue.shift()()
  }
 })
 ZMessage.instances.push(instance)
}

// 生成队列元素,延迟执行
ZMessage.prototype.saveToQueue = function (options) {
 return () => {
  this.setMessage(options)
 }
}

export default ZMessage


// 使用方式
import Vue from 'vue'
import ZMessage from 'path/to/ZMessage.js'
// 引入Element
// ....

// 自定义配置项
ZMessage.setConfig({ max: 1, isQueue: false, showNewest: true })

// 覆盖默认$message
Vue.prototype.$message = ZMessage

小结

希望看完本篇文章能对你拓展ElementUI框架的Message组件功能有所帮助。也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
IE和Firefox的Javascript兼容性总结[推荐收藏]
Oct 19 Javascript
JavaScript词法作用域与调用对象深入理解
Nov 29 Javascript
javascript结合ajax读取txt文件内容
Dec 05 Javascript
javascript实现简单的页面右下角提示信息框
Jul 31 Javascript
js判断鼠标位置是否在某个div中的方法
Feb 26 Javascript
用jQuery获取table中行id和td值的实现代码
May 19 Javascript
es6学习笔记之Async函数基本教程
May 11 Javascript
详解小程序如何动态绑定点击的执行方法
Nov 26 Javascript
JS window对象简单操作完整示例
Jan 14 Javascript
javascript实现的图片预览和上传功能示例【兼容IE 9】
May 01 Javascript
VSCode launch.json配置详细教程
Jun 18 Javascript
js+canvas实现五子棋小游戏
Aug 02 Javascript
js实现简易计算器功能
Oct 18 #Javascript
JavaScript实现更换背景图片
Oct 18 #Javascript
jquery轻量级数字动画插件countUp.js使用详解
Oct 17 #jQuery
CountUp.js数字滚动插件使用方法详解
Oct 17 #Javascript
CountUp.js实现数字滚动增值效果
Oct 17 #Javascript
countUp.js实现数字动态变化效果
Oct 17 #Javascript
jQuery/JS监听input输入框值变化实例
Oct 17 #jQuery
You might like
php字符串按照单词进行反转的方法
2015/03/14 PHP
PHP实现全角字符转为半角方法汇总
2015/07/09 PHP
PHP经典面试题之设计模式(经常遇到)
2015/10/15 PHP
CI映射(加载)数据到view层的方法
2016/03/28 PHP
php代码检查代理ip的有效性
2016/08/19 PHP
thinkphp 手机号和用户名同时登录
2017/01/20 PHP
PHP实现通过CURL上传文件功能示例
2018/05/30 PHP
使Ext的Template可以解析二层的json数据的方法
2007/12/22 Javascript
javascript 新浪背投广告实现代码
2009/07/07 Javascript
JavaScript Konami Code 实现代码
2009/07/29 Javascript
jQuery1.4.2与老版本json格式兼容的解决方法
2011/02/12 Javascript
jQuery中delegate与on的用法与区别示例介绍
2013/12/20 Javascript
JS记录用户登录次数实现代码
2014/01/15 Javascript
js生成的验证码的实现与技术分析
2014/09/17 Javascript
jquery模拟alert的弹窗插件
2015/07/31 Javascript
使用JQuery实现的分页插件分享
2015/11/05 Javascript
servlet+jquery实现文件上传进度条示例代码
2017/01/25 Javascript
轻松理解JavaScript之AJAX
2017/03/15 Javascript
关于预加载InstantClick的问题解决方法
2017/09/12 Javascript
初学者AngularJS的环境搭建过程
2017/10/27 Javascript
Angular实现的日程表功能【可添加及隐藏显示内容】
2017/12/27 Javascript
JavaScript实现百度搜索框效果
2020/03/26 Javascript
详解webpack4之splitchunksPlugin代码包分拆
2018/12/04 Javascript
JavaScript使用ul中li标签实现删除效果
2019/04/15 Javascript
Python查找相似单词的方法
2015/03/05 Python
python 巧用正则寻找字符串中的特定字符的位置方法
2018/05/02 Python
python使用__slots__让你的代码更加节省内存
2018/09/05 Python
Python&amp;&amp;GDAL实现NDVI的计算方式
2020/01/09 Python
html5+css3之CSS中的布局与Header的实现
2014/11/21 HTML / CSS
外语系毕业生自荐信范文
2013/12/16 职场文书
广告学毕业生求职信
2014/01/30 职场文书
老兵退伍标语
2014/10/07 职场文书
思想纪律作风整顿剖析材料
2014/10/11 职场文书
2015年大学迎新晚会总结
2015/07/16 职场文书
MySQL中int (10) 和 int (11) 的区别
2022/01/22 MySQL
springboot用户数据修改的详细实现
2022/04/06 Java/Android