vue中el-message的封装使用

目录
  • 前言
  • 实现方法
  • 方法一
  • 方法二
  • 方法三(有残缺的方法,可以带着问题看方法4)
  • 方法四
  • 方法五
  • 最后

前言

最近对项目进行改造,发现在el-message使用中,如果遇到服务器挂了或者在重启等其他情况,页面message会弹出一大堆报错信息,看起来很不美观,所以对el-message进行重写改造,这里记录下改造中遇到的问题和实现,希望能对你有点帮助。

实现方法

实现方法有很多种,可以根据你实际项目情况决定使用哪一种。

方法一

直接css里面给这个样式,简单省事,但是这样子有一个问题所有的message都重叠在一起,浅入浅出的动画效果不好,不是很推荐。

.el-message {
  top: 20px !important;
}

方法二

直接使用el-message的closeAll方法,弹消息之前关闭所有的消息,也很简单,但是这样会有一个明显的抖动,所以也不是很推荐(不介意的话也可以这样写)。

  this.$message.closeAll();
  this.$message.error("错误提示3");

方法三(有残缺的方法,可以带着问题看方法4)

对message进行改造,重写message方法,新建一个message.js,定义一个class类,给这个class赋予success,error,info,warning4个方法,根据el-message的使用方法,分为:this.$message.success('测试成功消息') 和this.$message({type:'success',message:'测试成功消息'})这两种情况,所以要根据传入的值是字符串还是对象做一下判断。

import { Message } from "element-ui";

class ZMessage {
  constructor() {
    ["success", "error", "info", "warning"].forEach((type) => {
      this[type] = function (options) {
        if (isObject(options)) {
          const { type='info', ...rest } = options;
          Message({
            type,
            ...rest,
          });
          return;
        }
        Message({
          type: type,
          message: options,
        });
      };
    });
  }
}

//判断传入的是否是Object
function isObject(content) {
  return (
    Object.prototype.toString.call(content) === "[object Object]" &&
    !!content.message
  );
}

export default new ZMessage;

然后在main.js里面引入,覆盖掉el-message的方法

import ZMessage from "@/utils/message";
Vue.prototype.$message = ZMessage;

这样message重写第一步就完成了,第二步需要判断当前message的数量,如果小于1,就弹消息,仔细观察message,我们可以通过document.getElementsByClassName("el-message").length来获取当前弹框的数量,如果大于等于1就不再弹框,如果小于1就弹框。

class ZMessage {
  constructor() {
    ["success", "error", "info", "warning"].forEach((type) => {
      this[type] = function (options) {
        //这里加一个判断
        if (document.getElementsByClassName("el-message").length === 0) {
          if (isConfig(options)) {
            const { type = "info", ...rest } = options;
            Message({
              type,
              ...rest,
            });
            return;
          }
          Message({
            type: type,
            message: options,
          });
        }
      };
    });
  }
}

这样弹消息即使多次触发,也只会弹一个消息出来,正当我以为已经完事了,却发现还有新的问题:

  • 问题1:this.$message({type:'error',message:'测试消息'}) 报错了
  • 问题2:弹的消息不会更新,必须要等上一条消息消失后,才会出现新的

方法四

对于方法三存在的两个问题,所以我们需要对方法三进行改造,还是那个文件message.js,这里不用class了,因为对外export的方法是new ZMessage(),message的值无法直接传递过来,暂时还没有想好咋传过来,所以就不用class了,所以对ZMessage进行下改造

const ZMessage = function (options) {
   if (isObject(options)) {
     const { type = "info", ...rest } = options;
      showMessage({
         type,
         ...rest,
       })
     return;
   }
     showMessage({
       type: options.type || "info",
       message: options,
     })
 };

 ["success", "error", "info", "warning"].forEach((type) => {
   ZMessage[type] = function (options) {
     if (isObject(options)) {
       ZMessage({
         type: type,
         ...options,
       });
       return;
     }
     ZMessage({
       type,
       message: options,
     });
   };
 });

function isObject(content) {
   return (
     Object.prototype.toString.call(content) === "[object Object]" &&
     !!content.message
   );
 }

function showMessage(options) {
   Message({
     ...options
   });
 }

 export default ZMessage;

这样第一个问题,this.$message({type:'error',message:'测试消息'})就不会报错了,接下来解决第二个问题,值不会更新的问题,可以定义一个msgInstance变量,如果有新的值来了,就关闭上一个消息

var msgInstance = null;
const ZMessage = function (options) {
 if (msgInstance) {
    //更新弹框
    msgInstance.close();
  }
   if (isObject(options)) {
     const { type = "info", ...rest } = options;
      showMessage({
         type,
         ...rest,
       })
     return;
   }
     showMessage({
       type: options.type || "info",
       message: options,
     })
 };

 ["success", "error", "info", "warning"].forEach((type) => {
   ZMessage[type] = function (options) {
     if (isObject(options)) {
       ZMessage({
         type: type,
         ...options,
       });
       return;
     }
     ZMessage({
       type,
       message: options,
     });
   };
 });

function isObject(content) {
   return (
     Object.prototype.toString.call(content) === "[object Object]" &&
     !!content.message
   );
 }

function showMessage(options) {
   msgInstance=Message({
     ...options
   });
 }

 export default ZMessage;

这样就完美解决了上面出现的两个问题,到这里目标基本已经实现;但是,又想到如果要求不止出现一个message,我要只出现两个甚至多个怎么办,所以在方法四的基础上,改造出来方法五,参考ant-design-vue,对最大数量可调配。

方法五

定义一个maxCount参数,需要message全局定义,在调用message方法之前,先定下message的最大数量,每次点击弹框的时候都往messageList里面插入一个当前的message实例,close的时候将这条数据删除,再给message新加一个config方法,maxCount就传给config方法,在这个里面配置。

import { Message } from "element-ui";
 // 定义message的当前数量
 var messageList = [];
 // 定义初始最大数量
 var messageMaxCount = 0;

 const ZMessage = function (options) {
   if (messageMaxCount && messageList.length >= messageMaxCount) {
     //更新弹框
     messageList[0].close();
   }
   if (isObject(options)) {
     const { type = "info", ...rest } = options;
     messageList.push(
       showMessage({
         type,
         ...rest,
       })
     );
     return;
   }
   messageList.push(
     showMessage({
       type: options.type || "info",
       message: options,
     })
   );
 };

 ["success", "error", "info", "warning"].forEach((type) => {
   ZMessage[type] = function (options) {
     if (isObject(options)) {
       ZMessage({
         type: type,
         ...options,
       });
       return;
     }
     ZMessage({
       type,
       message: options,
     });
   };
 });

 ZMessage.config = function (options) {
   const { maxCount } = options;
   if (maxCount) {
     if (typeof maxCount !== "number") {
       return console.error("参数类型错误:maxCount应为number类型");
     }
     messageMaxCount = maxCount;
   }
 };

 function isObject(content) {
   return (
     Object.prototype.toString.call(content) === "[object Object]" &&
     !!content.message
   );
 }

 function showMessage(options) {
   const { onClose:close, ...rest } = options;
   return Message({
     ...rest,
     //关闭时,除了传入的close方法,还需要将对应的实例删除
     onClose: (val) => {
       if(close){
         close()
       }
       messageList = messageList.filter((item) => item.id != val.id);
     },
   });
 }

 export default ZMessage;

使用:

 this.$message.config({
   maxCount:3
 })

最后

到这里,el-message就已经改造完毕,你可以根据自己的实际情况使用上面的任意方法,希望这个文章能对你有所帮助,还有其他的办法可以评论留言下,大家一起学习进步。

到此这篇关于vue中el-message的封装使用的文章就介绍到这了,更多相关vue el-message封装内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 基于vue写一个全局Message组件的实现

    不知道大家在用一些UI框架,比如Element-ui的时候,有没有觉得一些全局组件.this.$message(),this.Toast()等,用起来很爽.他们不像其他的组件,需要去导入,去注册.麻烦的很. 看了Element的源码,自己也撸了一个.其中包括了以前没有接触过的插件知识,哎,感觉自己对Vue的理解还是不够,只停留在了使用的这阶段.需要更多的往深层次的地方去钻.不说废话了,直接上代码. 效果演示 全局组件需要一个index.js文件去注册 BlogMessage.vue 这里的scr

  • Vue3封装 Message消息提示实例函数详解

    目录 Vue3封装 消息提示实例函数 样式布局封装 message.vue 功能实现 message.js 注册 自定义指令 使用 : 总结 Vue3封装 消息提示实例函数 Vue2.0使用 Vue.prototype.$message = function () {} vue3.0使用app.config.globalProperties挂载原型方法app.config.globalProperties.$message = Message 也支持直接导入函数使用 import Message

  • vue3手动封装弹出框组件message的方法

    本文实例为大家分享了vue3手动封装弹出框组件message的具体代码,供大家参考,具体内容如下 封装组件 <template> <Transition name="down"> <div class="xtx-message" :style="style[type]" v-show='isShow'> <!-- 上面绑定的是样式 --> <!-- 不同提示图标会变 --> <i

  • Vue3实现Message消息组件示例

    目录 组件设计 定义最终的组件 API 定义组件结构 模板和样式 模板 Template 消息图标 样式 组件脚本 创建组件实例 1.创建包裹容器,并设置外层的 Class 属性 2.创建实例并挂载到 body 3.其中定义取消挂载和重新设置 top 值的方法 实现渲染实例 API 在大多数 web 产品中,全局的 Message 组件占有较大的使用场景,它常出现在给与用户反馈.信息提示和与系统的对话场景中.如果使用传统的组件写法,则需要引入组件并在 components 中注册,然后再去模板中

  • 简单理解vue中el、template、replace元素

    本文实例为大家解析了vue中el.template.replace的元素,供大家参考,具体内容如下 api: http://cn.vuejs.org/api/#el el 类型: String | HTMLElement | Function 限制: 在组件定义中只能是函数. 详细: 为实例提供挂载元素.值可以是 CSS 选择符,或实际 HTML 元素,或返回 HTML 元素的函数.注意元素只用作挂载点.如果提供了模板则元素被替换,除非 replace 为 false.元素可以用 vm.$el

  • 详解vue中axios请求的封装

    axios Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中, 也是vue官方推荐使用的http库:封装axios,一方面为了以后维护方便,另一方面也可以对请求进行自定义处理 安装 npm i axios 封装 我把axios请求封装在http.js中,重新把get请求,post请求封装了一次 首先,引入axios import axios from 'axios' 设置接口请求前缀 一般我们开发都会有开发.测试.生产环境,前缀需要加以区分,我们利用

  • 如何在vue中更优雅的封装第三方组件详解

    目录 一.需求场景描述 二.关键技术点介绍 1.v-bind="$attrs" 2.v-on="$listeners" 三.封装el-image的代码示例 总结 一.需求场景描述 实际开发的时候,为了减少重复造轮子,提高工作效率,节省开发时间成本, 免不了会使用ui组件库,比如在web前端很受欢迎的element-ui. 但有的时候,我们需要在原组件的基础上做些改造,比如一个image组件, 我们需要统一在图片加载失败的时候展示的特定图,每次使用组件都加一遍, 麻烦

  • vue中axios请求的封装实例代码

    axios Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中, 也是vue官方推荐使用的http库:封装axios,一方面为了以后维护方便,另一方面也可以对请求进行自定义处理 安装 npm i axios 封装 我把axios请求封装在http.js中,重新把get请求,post请求封装了一次 首先,引入axios import axios from 'axios' 设置接口请求前缀 一般我们开发都会有开发.测试.生产环境,前缀需要加以区分,我们利用

  • vue中使用svg封装全局消息提示组件

    本文实例为大家分享了vue中使用svg封装全局消息提示组件的具体代码,供大家参考,具体内容如下 先看效果图 一.首先安装下载需要用到的svg相关依赖 npm install svg-sprite-loader --save-dev 二.针对没有vue.config.js文件的vue项目,直接在webpack.base.conf.js中进行如下两个配置 1.找到图片相关配置位置,添加款选出的代码 2.在图片配置后添加如下代码 三.根据添加的代码我们去src下创建一个icons文件夹,icons下面

  • 在vue中封装可复用的组件方法

    本次封装的组件以toast组件为例 以前使用移动端ui插件时,通过一句代码比如 $.toast( ' 需要显示的内容 ' ),从而在页面上展示这段文字,并在一定时间后消失. 现在我们也尝试自己封装toast组件. 准备工作:vue-cli脚手架工程 先看一下涉及到的文件目录截图: 这次的封装主要涉及的文件是Toast.vue toast.js Hello.vue,主要思路如下: ① Toast.vue是我们要使用的toast组件: ② toast.js里面用Vue.extend()扩展一个组件构

  • 详解vue中axios的使用与封装

    分享下我自己的axios封装 axios是个很好用的插件,都是一些params对象,所以很方便做一些统一处理 当然首先是npm安装axios 很简单$ npm install axios --save 在src下新建文件夹 service / index.js 接着上代码 import axios from 'axios'; import { Toast} from 'mint-ui';// 我用的mint的框架来弹出我的错误返回 大家可以用别的提示 import router from '..

  • Vue中axios的封装(报错、鉴权、跳转、拦截、提示)

    统一捕获接口报错 弹窗提示 报错重定向 基础鉴权 表单序列化 实现的功能 统一捕获接口报错 : 用的axios内置的拦截器 弹窗提示: 引入 Element UI 的 Message 组件 报错重定向: 路由钩子 基础鉴权: 服务端过期时间戳和token,还有借助路由的钩子 表单序列化: 我这边直接用 qs (npm模块),你有时间也可以自己写 用法及封装 用法 // 服务层 , import默认会找该目录下index.js的文件,这个可能有小伙伴不知道 // 可以去了解npm的引入和es6引入

  • 关于Vue中axios的封装实例详解

    前言 axios 是 Vue 官方推荐的一个 HTTP 库,用 axios 官方简介来介绍它,就是: Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中. 作为一个优秀的 HTTP 库,axios 打败了曾经由 Vue 官方团队维护的 vue-resource,获得了 Vue 作者尤小右的大力推荐,成为了 Vue 项目中 HTTP 库的最佳选择. 虽然,axios 是个优秀的 HTTP 库,但是,直接在项目中使用并不是那么方便,所以,我们需要对其进行一

  • vue中axios的二次封装实例讲解

    我们做项目时,虽然axios也可以直接拿来用,但是对接口比较零散,不太好进行维护,也会产生大量的重复代码,所以我在这对axios进行了统一接口处理 第一步,先在src中的公共文件夹中如utils里新建request.js文件 import axios from 'axios' import router from '@/router/routers' import { Notification, MessageBox } from 'element-ui' import store from '

随机推荐