在最近項目開發(fā)中,接口錯誤信息是在攔截器統(tǒng)一處理犬钢,在一次產(chǎn)品大大驗收過程中稠氮,由于服務器沒有重啟完成,導致前端彈出一推錯誤提示語昨寞,產(chǎn)品大大對于提示語的交互效果提出了一系列的建議瞻惋。由于項目使用了ElementUI
框架,加上本人喜歡投(xin)機(shou)仍摇(nian)巧(lai)歼狼,于是去查看ElementUI
Message
的源碼,根據(jù)實際需求自定義了Message
功能享怀。
場景描述
場景一:限制頁面同時展示消息提示語的最大數(shù)量(優(yōu)先展示后插入的提示語)
場景二:根據(jù)不同情況可以優(yōu)先顯示新/舊消息提示語
場景三:如果超出了最大顯示數(shù)量羽峰,則剩余的消息以隊列的顯示依次展示
實現(xiàn)方案
場景一
-
功能描述
根據(jù)設置的最大數(shù)量,如果存儲的實例列表
instances
長度超出最大限制數(shù)則銷毀之前的消息實例instance
(調(diào)用Message方法創(chuàng)建消息提示語會返回當前消息的一個實例),否則保存新建實例instance
到實例列表instances
中如果消息提示語消失梅屉,需要從實例列表
instances
中移除當前實例instance
值纱,確保頁面顯示消息數(shù)量與instances
列表長度統(tǒng)一
-
代碼實現(xiàn)
新建
ZMessage
構(gòu)造函數(shù)import { Message } from 'element-ui' function ZMessage (options) { if (!(this instanceof ZMessage)) { return new ZMessage(options) } this.init(options) }
靜態(tài)配置項和實例列表
ZMessage.config = { max: 0, // 最大顯示數(shù) } ZMessage.instances = [] // 消息體實例列表
定義創(chuàng)建消息和監(jiān)聽實例消失事件方法
ZMessage.prototype.setMessage = function (options) { const instance = Message(options) // 監(jiān)聽消息消失事件,從實例列表移除當前消息實例 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 // 判斷如果超出最大消息數(shù)時坯汤,刪除消息 if (max > 0 && ZMessage.instances.length >= max) { this.removeMessages() : } if (ZMessage.instances.length < max || !max) { this.setMessage(options) } }
場景二
-
功能描述
- 在場景一的基礎(chǔ)上新增優(yōu)先取消息還是舊消息的標志操作
-
代碼實現(xiàn)
靜態(tài)配置項和實例列表
ZMessage.config = { max: 0, // 最大顯示數(shù) showNewest: true // 是否后添加的消息覆蓋前面的消息 }
初始化
ZMessage.prototype.init = function (options) { const { max, showNewest } = ZMessage.config // 判斷如果超出最大消息數(shù)時虐唠,刪除消息 if (max > 0 && ZMessage.instances.length >= max && showNewest) { this.removeMessages() } if (ZMessage.instances.length < max || !max) { this.setMessage(options) } }
場景三
-
功能描述
在場景一場景二基礎(chǔ)上添加是否使用隊列方式存儲未展示消息的實例,如果超出了最大限制數(shù)則創(chuàng)建消息實例的容器存儲到消息隊列
queue
中監(jiān)聽是否有消息消失惰聂,如果有則從消息隊列
queue
中取出第一個容器疆偿,創(chuàng)建消息實例
-
代碼實現(xiàn)
靜態(tài)配置項和消息容器隊列
ZMessage.config = { max: 0, // 最大顯示數(shù) showNewest: true, // 是否后添加的消息覆蓋前面的消息 isQueue: false // 是否以隊列形式存儲為展示消息 } ZMessage.queue = [] // 未展示數(shù)據(jù)的消息容器隊列
生成隊列
// 生成隊列元素,延遲執(zhí)行 ZMessage.prototype.saveToQueue = function (options) { return () => { this.setMessage(options) } }
初始化
// 初始化 ZMessage.prototype.init = function (options) { const { max, isQueue, showNewest } = ZMessage.config // 判斷如果超出最大消息數(shù)時搓幌,刪除消息 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) } }
獲取消息實例和添加事件監(jiān)聽
// 獲取消息實例和添加事件監(jiān)聽 ZMessage.prototype.setMessage = function (options) { const instance = Message(options) // 監(jiān)聽消息消失事件杆故,從實例列表移除當前消息實例 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) }
最后一步
添加不同消息類型功能靜態(tài)方法
const messageTypes = ['success', 'warning', 'error', 'info']
// 各消息類型靜態(tài)方法
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 = [] // 未展示數(shù)據(jù)的消息隊列
ZMessage.instances = [] // 消息體實例列表
// 配置項
ZMessage.config = {
max: 0, // 最大顯示數(shù)
isQueue: false, // 是否以隊列形式存儲為展示消息
showNewest: true // 是否后添加的消息覆蓋前面的消息
}
// 配置參數(shù)
ZMessage.setConfig = function (config = {}) {
ZMessage.config = { ...ZMessage.config, ...config }
}
ZMessage.close = Message.close
ZMessage.closeAll = Message.closeAll
// 各消息類型靜態(tài)方法
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
// 判斷如果超出最大消息數(shù)時,刪除消息
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
})
}
// 獲取消息實例和添加事件監(jiān)聽
ZMessage.prototype.setMessage = function (options) {
const instance = Message(options)
// 監(jiān)聽消息消失事件溉愁,從實例列表移除當前消息實例
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)
}
// 生成隊列元素处铛,延遲執(zhí)行
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
小結(jié)
希望看完本篇文章能對你拓展ElementUI框架的Message組件功能有所幫助。
文中如有錯誤拐揭,歡迎在評論區(qū)指正撤蟆,如果這篇文章有幫助到你,歡迎點贊和關(guān)注投队。