Element-UI之Message功能拓展

在最近項(xiàng)目開發(fā)中,接口錯(cuò)誤信息是在攔截器統(tǒng)一處理,在一次產(chǎn)品大大驗(yàn)收過(guò)程中,由于服務(wù)器沒有重啟完成,導(dǎo)致前端彈出一推錯(cuò)誤提示語(yǔ),產(chǎn)品大大對(duì)于提示語(yǔ)的交互效果提出了一系列的建議。由于項(xiàng)目使用了ElementUI框架,加上本人喜歡投(xin)機(jī)(shou)?。╪ian)巧(lai),于是去查看ElementUI Message的源碼,根據(jù)實(shí)際需求自定義了Message功能。

場(chǎng)景描述

  • 場(chǎng)景一:限制頁(yè)面同時(shí)展示消息提示語(yǔ)的最大數(shù)量(優(yōu)先展示后插入的提示語(yǔ))

  • 場(chǎng)景二:根據(jù)不同情況可以優(yōu)先顯示新/舊消息提示語(yǔ)

  • 場(chǎng)景三:如果超出了最大顯示數(shù)量,則剩余的消息以隊(duì)列的顯示依次展示

實(shí)現(xiàn)方案

場(chǎng)景一

  • 功能描述

    • 根據(jù)設(shè)置的最大數(shù)量,如果存儲(chǔ)的實(shí)例列表instances長(zhǎng)度超出最大限制數(shù)則銷毀之前的消息實(shí)例instance(調(diào)用Message方法創(chuàng)建消息提示語(yǔ)會(huì)返回當(dāng)前消息的一個(gè)實(shí)例),否則保存新建實(shí)例instance到實(shí)例列表instances

    • 如果消息提示語(yǔ)消失,需要從實(shí)例列表instances中移除當(dāng)前實(shí)例instance,確保頁(yè)面顯示消息數(shù)量與instances列表長(zhǎng)度統(tǒng)一

  • 代碼實(shí)現(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)配置項(xiàng)和實(shí)例列表

    
    ZMessage.config = {
    
      max: 0, // 最大顯示數(shù)
    
    }
    
    
    
    ZMessage.instances = [] // 消息體實(shí)例列表
    
    

    定義創(chuàng)建消息和監(jiān)聽實(shí)例消失事件方法

    
    ZMessage.prototype.setMessage = function (options) {
    
      const instance = Message(options)
    
      // 監(jiān)聽消息消失事件,從實(shí)例列表移除當(dāng)前消息實(shí)例
    
      instance.$watch('visible', val => {
    
        ZMessage.instances = ZMessage.instances.filter(item => item !== instance)
    
      })
    
      ZMessage.instances.push(instance)
    
    }
    
    

    定義移除消息實(shí)例方法

    
    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ù)時(shí),刪除消息
    
      if (max > 0 && ZMessage.instances.length >= max) {
    
        this.removeMessages() :
    
      }
    
      if (ZMessage.instances.length < max || !max) {
    
        this.setMessage(options)
    
      }
    
    }
    
    

場(chǎng)景二

  • 功能描述

    • 在場(chǎng)景一的基礎(chǔ)上新增優(yōu)先取消息還是舊消息的標(biāo)志操作
  • 代碼實(shí)現(xiàn)

    靜態(tài)配置項(xiàng)和實(shí)例列表

    
    ZMessage.config = {
    
      max: 0, // 最大顯示數(shù)
    
      showNewest: true // 是否后添加的消息覆蓋前面的消息
    
    }
    
    

    初始化

    
    ZMessage.prototype.init = function (options) {
    
      const { max, showNewest } = ZMessage.config
    
      // 判斷如果超出最大消息數(shù)時(shí),刪除消息
    
      if (max > 0 && ZMessage.instances.length >= max && showNewest) {
    
        this.removeMessages()
    
      }
    
      if (ZMessage.instances.length < max || !max) {
    
        this.setMessage(options)
    
      }
    
    }
    
    

場(chǎng)景三

  • 功能描述

    • 在場(chǎng)景一場(chǎng)景二基礎(chǔ)上添加是否使用隊(duì)列方式存儲(chǔ)未展示消息的實(shí)例,如果超出了最大限制數(shù)則創(chuàng)建消息實(shí)例的容器存儲(chǔ)到消息隊(duì)列queue

    • 監(jiān)聽是否有消息消失,如果有則從消息隊(duì)列queue中取出第一個(gè)容器,創(chuàng)建消息實(shí)例

  • 代碼實(shí)現(xiàn)

    靜態(tài)配置項(xiàng)和消息容器隊(duì)列

    
    ZMessage.config = {
    
      max: 0, // 最大顯示數(shù)
    
      showNewest: true, // 是否后添加的消息覆蓋前面的消息
    
      isQueue: false // 是否以隊(duì)列形式存儲(chǔ)為展示消息
    
    }
    
    
    
    ZMessage.queue = [] // 未展示數(shù)據(jù)的消息容器隊(duì)列
    
    

    生成隊(duì)列

    
    // 生成隊(duì)列元素,延遲執(zhí)行
    
    ZMessage.prototype.saveToQueue = function (options) {
    
      return () => {
    
        this.setMessage(options)
    
      }
    
    }
    
    

    初始化

    
    // 初始化
    
    ZMessage.prototype.init = function (options) {
    
      const { max, isQueue, showNewest } = ZMessage.config
    
      // 判斷如果超出最大消息數(shù)時(shí),刪除消息
    
      if (max > 0 && ZMessage.instances.length >= max && showNewest && !isQueue) {
    
        this.removeMessages()
    
      }
    
    
    
      if (ZMessage.instances.length >= max && isQueue) {
    
        // 添加隊(duì)列元素
    
        ZMessage.queue.push(this.saveToQueue(options))
    
      } else if (ZMessage.instances.length < max || !max) {
    
        this.setMessage(options)
    
      }
    
    }
    
    

    獲取消息實(shí)例和添加事件監(jiān)聽

    
    // 獲取消息實(shí)例和添加事件監(jiān)聽
    
    ZMessage.prototype.setMessage = function (options) {
    
      const instance = Message(options)
    
      // 監(jiān)聽消息消失事件,從實(shí)例列表移除當(dāng)前消息實(shí)例
    
      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ù)的消息隊(duì)列

ZMessage.instances = [] // 消息體實(shí)例列表

// 配置項(xiàng)

ZMessage.config = {

  max: 0, // 最大顯示數(shù)

  isQueue: false, // 是否以隊(duì)列形式存儲(chǔ)為展示消息

  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ù)時(shí),刪除消息

  if (max > 0 && ZMessage.instances.length >= max && showNewest && !isQueue) {

    this.removeMessages()

  }

  if (ZMessage.instances.length >= max && isQueue) {

    // 添加隊(duì)列元素

    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

  })

}

// 獲取消息實(shí)例和添加事件監(jiān)聽

ZMessage.prototype.setMessage = function (options) {

  const instance = Message(options)

  // 監(jiān)聽消息消失事件,從實(shí)例列表移除當(dāng)前消息實(shí)例

  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)

}

// 生成隊(duì)列元素,延遲執(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

// ....

// 自定義配置項(xiàng)

ZMessage.setConfig({ max: 1, isQueue: false, showNewest: true })

// 覆蓋默認(rèn)$message

Vue.prototype.$message = ZMessage

小結(jié)

希望看完本篇文章能對(duì)你拓展ElementUI框架的Message組件功能有所幫助。

文中如有錯(cuò)誤,歡迎在評(píng)論區(qū)指正,如果這篇文章有幫助到你,歡迎點(diǎn)贊和關(guān)注。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容