element-ui message 组件源码分享

news2024/11/27 14:30:23

今日简单分享 message 组件的源码,主要从以下四个方面来分享:

1、message 组件的页面结构

2、message 组件的 options 配置

3、mesage 组件的方法

4、个人总结

一、message 组件的页面结构

二、message 组件的 options 配置

前置说明:message 并没有注册到 Vue 实例上,而是创建了一个构造函数,并将其添加到 Vue 的原型链上,可在任何一个 Vue 组件内部通过 this.$message 的方式访问。

main.js 代码位置:

main.js 的代码讲解,主要有三个功能功能:

  • 将 Message 实例化,并挂载到 body 中。
  • 处理一个页面多个实例对象的情况。如果一个页面多个实例对象,使用数组的方式存储,并改变每个实例对象垂直方向的偏移量。
  • 关闭的事件回调。处理当页面有多个实例对象时,关闭 Message 时,移除当前实例对象额高度,并调整其他实例对象的高度。设置关闭后的回调函数。
import Vue from "vue";
import Main from "./main.vue";
import { PopupManager } from "element-ui/src/utils/popup";
import { isVNode } from "element-ui/src/utils/vdom";
import { isObject } from "element-ui/src/utils/types";
let MessageConstructor = Vue.extend(Main);

// 定义实例对象
let instance;
// 存储多个实例对象
let instances = [];
// 定义一个 id 的变量
let seed = 1;

// 工厂函数 创建和显示消息
const Message = function(options) {
  // 为服务端渲染时 返回
  if (Vue.prototype.$isServer) return;
  // 接收配置对象
  options = options || {};
  // 如果 options 为字符传 则转为对象格式
  if (typeof options === "string") {
    options = {
      message: options,
    };
  }
  // 接收父组件传递过来的 onClose 方法
  let userOnClose = options.onClose;
  // 设置每个 id class 类名
  let id = "message_" + seed++;

  // 关闭的函数,调用 Message 的 close 方法
  options.onClose = function() {
    // 父组件调用实例对象中的关闭方法
    Message.close(id, userOnClose);
  };
  // 创建新的 Vue实例对象 MessageConstructor,并将其赋值给 instace 变量
  instance = new MessageConstructor({
    data: options,
  });
  // 设置当前实例的 id 值,此 id 作为当前实例的唯一标识
  instance.id = id;
  // 如果是虚拟dom
  if (isVNode(instance.message)) {
    instance.$slots.default = [instance.message];
    instance.message = null;
  }
  // 将 instance 这个 Vue 实例挂载到 $el 属性所引用的 dom 元素上
  instance.$mount();
  // 将 dom 元素添加到 body 中
  document.body.appendChild(instance.$el);
  // 设置垂直方向的偏移量
  let verticalOffset = options.offset || 20;
  // 遍历实例对象数组,并将每个实例对象的高度增加 16,作用是计算每个实例对象垂直方向的偏移量
  instances.forEach((item) => {
    verticalOffset += item.$el.offsetHeight + 16;
  });
  // 设置当前实例对象垂直方向的偏移量
  instance.verticalOffset = verticalOffset;
  // 设置当前实例对象可见,即 Main 组件可见
  instance.visible = true;
  // 设置当前实例的层级,如果页面上有 n 个实例对象,每点击一次 zIndex 就增加 n
  // 作用是保证每次新弹出的 message 弹框都在上次的 message 弹出层之上
  instance.$el.style.zIndex = PopupManager.nextZIndex();
  // 将当前实例对象存到实例对象数组当中
  instances.push(instance);
  // 返回当前实例对象
  return instance;
};

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

// Message 定义 close 关闭方法,传入两个参数,当前实例对象的 id 和 onClose 方法
// id 为一个带有 id 参数的 className 类名
// userOnClose 为父组件传递过来的 onClose 方法
Message.close = function(id, userOnClose) {
  let len = instances.length;
  let index = -1;
  let removedHeight;
  for (let i = 0; i < len; i++) {
    // 关闭的当前实例对象的 id 等于实例对象组中的 id,则获取垂直方向的偏移量,并更新当前的索引
    if (id === instances[i].id) {
      removedHeight = instances[i].$el.offsetHeight;
      index = i;
      // 如果父组件传递过来的 onClose 是一个回调函数,则将当前实例对象回传给父组件
      if (typeof userOnClose === "function") {
        userOnClose(instances[i]);
      }
      // 删除实例对象组中的当前实例
      instances.splice(i, 1);
      break;
    }
  }
  // 如果页面无 instance 实例对象,返回
  if (len <= 1 || index === -1 || index > instances.length - 1) return;
  // 将当前实例对象后面的实例对象的垂直方向的偏移量的高度上移
  for (let i = index; i < len - 1; i++) {
    let dom = instances[i].$el;
    dom.style["top"] =
      parseInt(dom.style["top"], 10) - removedHeight - 16 + "px";
  }
};

// closeAll 关闭所有实例对象
Message.closeAll = function () {
  for (let i = instances.length - 1; i >= 0; i--) {
    // 关闭当前实例对象
    instances[i].close();
  }
};

export default Message;

isNode 方法:

2.1 message 属性,消息文字,类型 string / VNode,无默认值。

2.2 type 属性,主题,类型 string,success/warning/info/error,默认 info。

2.3 iconClass 属性,自定义图标的类名,会覆盖 type,类型 string,无默认值。

2.4 dangerouslyUseHTMLString 属性,是否将 message 属性作为 HTML 片段处理,类型 boolean,默认 false。

2.5 customClass 属性,自定义类名,类型 string,无默认值。

2.6 duration 属性,显示时间, 毫秒。设为 0 则不会自动关闭,类型 boolean,默认 false。

2.7 showClose 属性,是否显示关闭按钮,类型 boolean,默认 false。

2.8 center 属性,文字是否居中,类型 boolean,默认 false。

2.9 onClose 方法,关闭时的回调函数, 参数为被关闭的 message 实例,类型 function,无默认值。

2.10 offset 属性,Message 距离窗口顶部的偏移量,类型 number,默认 20。

三、message 组件的方法

3.1 close 关闭当前的 Message。

close 方法使用的代码:

展示效果如下:

3.2 closeAll 手动关闭所有 Message。

方法使用的代码如下:

展示效果如下:

四、个人总结

第一次研究动态创建组件实例,有两个心得:

4.1 和模板中静态声明组件略有不同,核心点是使用 Vue.extend,创建可复用组件构造器。

4.2 动态创建组件灵活性高,主要表现在它是编程式的,可以很方便的进行手动调用,而模板创建的组件则更易于理解和维护,各有不同的使用场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1562854.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Centos7 安装 Oracle19c

下载oracle预安装包 wget http://yum.oracle.com/repo/OracleLinux/OL7/latest/x86_64/getPackage/oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm 下载19c安装包 https://www.oracle.com/cn/database/technologies/oracle-database-software-downloads.html#19c 选择…

OpenLayers6实战,OpenLayers实现鼠标拖拽绘制三角形,OpenLayers自定义绘制特殊图形

专栏目录: OpenLayers实战进阶专栏目录 前言 本章讲解使用OpenLayers如何绘制三角形。 OpenLayers本身是可以通过多边形绘制来绘制自行绘制三角形的,但是这种绘制方式是通过鼠标点击每个点来实现线条链接的,不支持固定的三角形这种特殊图形绘制的。 因此本章我们通过自定义…

Express.js项目实战(1)—— 我的藏书馆

首先新建文件夹——myLibrary 在vscode中点击文件>点击 Duplicate Workspace(以工作区的方式打开文件夹myLibrary) 点击duplicate Workspace&#xff08;打开工作区&#xff09; 之后&#xff0c;会出现以下界面 点击打开文件夹&#xff0c;选择新建的文件夹&#xff0c;会出…

服务器托管让服务器管理更轻松高效

在信息化飞速发展的今天&#xff0c;服务器作为企业数据处理和信息存储的核心设备&#xff0c;其管理的重要性日益凸显。服务器托管&#xff0c;作为一种高效、专业的服务器管理方式&#xff0c;正逐渐成为众多企业的首选。那么&#xff0c;服务器托管究竟是如何让服务器管理更…

GEE:基于光谱距离方法的变化检测(以滑坡为例)

作者:CSDN @ _养乐多_ 本文将介绍在 Google Earth Engine(GEE)平台上,使用光谱向量距离度量方法进行变化检测的代码。代码中使用哨兵数据的光谱向量,并以检测滑坡为例进行演示。 结果如下图所示, 文章目录 一、参考内容1.1 光谱距离1.2 点积二、代码链接三、完整代码一…

Linux中查看文件内容的命令

文章目录 一、七类常见的Linux的文件二、显示命令三、分页显示四、显示文件前后内容五、压缩、解压缩六、补充 一、七类常见的Linux的文件 字符文件类型-普通文件&#xff0c;包括纯文本文件、二进制文件、各种压缩文件等。在find命令中&#xff0c;type 选项中用 f来表示d目录…

GoogleNet神经网络介绍

一、简介 GoogleNet&#xff0c;也称为GoogLeNet&#xff0c;是谷歌工程师设计的一种深度神经网络结构&#xff0c;它在2014年的ImageNet图像识别挑战赛中取得了冠军。该神经网络的设计特点主要体现在其深度和宽度上&#xff0c;通过引入名为Inception的核心子网络结构&#x…

【Jmeter+Influxdb+Grafana性能监控平台安装与部署】

JmeterInfluxdbGrafana性能监控平台安装与部署 前言Influxdb安装与连接Jmeternfluxdb下载&#xff08;winodws&#xff09;Grafana安装与配置 前言 我们在性能测试过程中&#xff0c;在需要较大并发时&#xff0c;为了尽量避免使用GUI界面来节省资源&#xff0c;通常使用命令行…

SAP-怎么查一个帐号访问事务代码的记录或者一个事务代码的被访问记录

起因 上周六&#xff0c;查了某用户对某事务代码的访问记录。今天又要查类似的信息。我发现我居然忘了该怎么查了。于是在处理完事情之后&#xff0c;整理了查询的过程&#xff0c;形成了这篇文章。 经过 热心网友告诉了我一个事务代码&#xff1a;ST03N - 工作负载和性能统…

[Python学习篇] Python解释器

解释器的作用 Python解释器&#xff08;Interpreter&#xff09;的作用&#xff0c;通俗理解&#xff0c;就是起到一个翻译的作用&#xff0c;把程序员所编写的代码翻译为计算机能读懂执行的代码。简单地说&#xff0c;Python解释器对输入的Python代码进行解释和执行。Python解…

强!10.6K star,一款开源HTTP测试工具,适合新手,简单、容易上手!

大家好&#xff0c;我是狂师&#xff01; 今天给大家推荐一款开源的HTTP测试工具&#xff1a;Hurl&#xff0c;相比curl、wget功能更强大&#xff0c;且更容易上手、很适用新手使用。 1、项目介绍 Hurl是一个使用Rust语言开发的命令行工具&#xff0c;它允许用户运行以简单纯…

EasyExcel 复杂表头的导出(动态表头和静态表头)

问题&#xff1a;如图&#xff0c;1部分的表头是动态的根据日期变化&#xff0c;2部分是数据库对应的字段&#xff0c;静态不变的&#xff1b; 解决方案&#xff1a;如果不看1的部分&#xff0c;2部分内容可以根据实体类注解的方式导出&#xff0c;那么我们是不是可以先将动态表…

linux内核网络分析-通用字段“每日读书”

这一节讨论sk_buff的主要字段&#xff0c;而这些字段都与特定的内核功能无关。 struct timeval stamp; 通常只对一个已经接收的封包才有意义&#xff0c;这是一个时间戳&#xff0c;用于避哦啊是封包何时被接收&#xff0c;或者有时候用于表示封包预定传输的时间&#xff0c;此…

护眼台灯哪个牌子最好,护眼台灯五大品牌墙裂分享

近视在儿童中愈发普遍&#xff0c;许多家长开始认识到&#xff0c;除了学业成绩之外&#xff0c;孩子的视力健康同样重要。毕竟&#xff0c;学业的落后可以逐渐弥补&#xff0c;而一旦孩子近视&#xff0c;眼镜便可能成为长期伴随。因此&#xff0c;专业的护眼台灯对于每个家庭…

钉钉服务端API报错 43008 参数需要multipart类型

钉钉服务端API报错 43008 参数需要multipart类型 problem 使用媒体文件上传接口&#xff0c;按照文档输入参数&#xff0c;结果返回报错 # 参数 {"access_token": "xxx""type": "image","media": "/Users/xxx/xxx/s…

上位机图像处理和嵌入式模块部署(qmacvisual之n点标定)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 工业场景中&#xff0c;很多时候图像是用来做测量的。虽然我们很希望载台是平的&#xff0c;摄像头是正对着拍摄物体的&#xff0c;但是运行时间长…

String类教程:如何在Java中使用字符串操作

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

【洛谷】P9240 [蓝桥杯 2023 省 B] 冶炼金属

题目链接 P9240 [蓝桥杯 2023 省 B] 冶炼金属 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路 这道题可以用数学的方法去做&#xff0c;但是我想不到&#x1f607;有兴趣的可以去看看数学的题解 比较简单的思路就是二分查找&#xff0c;轻松简单不费脑&#xff0c;带你…

深信服超融合虚拟机的导入方法

以从vmware虚拟机导出的虚拟机为例。 1 进入虚拟机页面点【新增】&#xff0c;选择【导入虚拟机】 2 以文件类型为ovf、mf、vmdk为例导入 选择文件类型&#xff0c;选择那三个导出的虚拟机的文件&#xff0c;选择分组&#xff0c;存储位置和运行位置默认&#xff0c;操作系统…

翻译学习(英译汉)

2024-04-02 翻译词组&#xff1a;shrinking deficits 我的练习&#xff1a;财政赤字 问题 1&#xff1a;shrinking deficits 怎么理解&#xff0c;在中文应该怎么称呼 问题 2&#xff1a;Shrinking deficits 可以译为中文多种句式吗 AI助手 Kimi.ai - 帮你看更大的世界 (…