element message-box源码
Posted wsk1576025821
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了element message-box源码相关的知识,希望对你有一定的参考价值。
本文参考https://www.cnblogs.com/fangnianqin/p/10769949.html
src/main.vue
<template> <transition name="msgbox-fade"> <!--包裹弹框的div--> <div class="el-message-box__wrapper" tabindex="-1" v-show="visible" @click.self="handleWrapperClick" role="dialog" aria-modal="true" :aria-label="title || ‘dialog‘"> <!--中间的弹框--> <div class="el-message-box" :class="[customClass, center && ‘el-message-box--center‘]"> <!--弹窗头部,包含:标题和关闭按钮;title必须设置,如果不设置不显示头部信息--> <div class="el-message-box__header" v-if="title !== null"> <!--头部标题--> <div class="el-message-box__title"> <!--center为true时,为居中布局,可设置图标,图标和标题居中显示--> <div :class="[‘el-message-box__status‘, icon]" v-if="icon && center"> </div> <span> title </span> </div> <button type="button" class="el-message-box__headerbtn" aria-label="Close" v-if="showClose" @click="handleAction(distinguishCancelAndClose ? ‘close‘ : ‘cancel‘)" @keydown.enter="handleAction(distinguishCancelAndClose ? ‘close‘ : ‘cancel‘)"> <i class="el-message-box__close el-icon-close"></i> </button> </div> <!--弹框内容部分--> <div class="el-message-box__content"> <!--消息类型的图标--> <div :class="[‘el-message-box__status‘, icon]" v-if="icon && !center && message !== ‘‘"> </div> <!--弹框的主要内容--> <div class="el-message-box__message" v-if="message !== ‘‘"> <slot> <!--dangerouslyUsehtmlString是否将 message 属性作为 HTML 片段处理,如果该字段不存在时,直接显示message--> <p v-if="!dangerouslyUseHTMLString"> message </p> <!--如果存在将message作为HTML处理--> <p v-else v-html="message"></p> </slot> </div> <!--输入框部分,根据设置的showInput显示--> <div class="el-message-box__input" v-show="showInput"> <el-input v-model="inputValue" :type="inputType" @keydown.enter.native="handleInputEnter" :placeholder="inputPlaceholder" ref="input"></el-input> <!--检验错误的提示信息--> <div class="el-message-box__errormsg" :style=" visibility: !!editorErrorMessage ? ‘visible‘ : ‘hidden‘ "> editorErrorMessage </div> </div> </div> <!--弹框底部,包含:确认、取消按钮--> <div class="el-message-box__btns"> <el-button :loading="cancelButtonLoading" :class="[ cancelButtonClasses ]" v-if="showCancelButton" :round="roundButton" size="small" @click.native="handleAction(‘cancel‘)" @keydown.enter="handleAction(‘cancel‘)"> cancelButtonText || t(‘el.messagebox.cancel‘) </el-button> <el-button :loading="confirmButtonLoading" ref="confirm" :class="[ confirmButtonClasses ]" v-show="showConfirmButton" :round="roundButton" size="small" @click.native="handleAction(‘confirm‘)" @keydown.enter="handleAction(‘confirm‘)"> confirmButtonText || t(‘el.messagebox.confirm‘) </el-button> </div> </div> </div> </transition> </template> <script type="text/babel"> import Popup from ‘element-ui/src/utils/popup‘; import Locale from ‘element-ui/src/mixins/locale‘; import ElInput from ‘element-ui/packages/input‘; import ElButton from ‘element-ui/packages/button‘; import addClass, removeClass from ‘element-ui/src/utils/dom‘; import t from ‘element-ui/src/locale‘; import Dialog from ‘element-ui/src/utils/aria-dialog‘; let messageBox; //定义的图标类型 let typeMap = success: ‘success‘, info: ‘info‘, warning: ‘warning‘, error: ‘error‘ ; export default mixins: [Popup, Locale], props: modal: default: true , // 是否在 MessageBox 出现时将 body 滚动锁定 lockScroll: default: true , // MessageBox 是否显示右上角关闭按钮 showClose: type: Boolean, default: true , // 是否可通过点击遮罩关闭 MessageBox boolean — true(以 alert 方式调用时为 false) closeOnClickModal: default: true , // 是否可通过按下 ESC 键关闭 MessageBox boolean — true(以 alert 方式调用时为 false) closeOnPressEscape: default: true , // 是否在 hashchange 时关闭 MessageBox boolean — true closeOnHashChange: default: true , // 是否居中布局 center: default: false, type: Boolean , // 是否使用圆角按钮 roundButton: default: false, type: Boolean , components: ElInput, ElButton , computed: icon() const type, iconClass = this; //如果用户设置了自定义图标的类名,就显示自定义图标;如果没有就显示设置的type图标,否则就不显示图标 return iconClass || (type && typeMap[type] ? `el-icon-$ typeMap[type] ` : ‘‘); , //添加确定按钮的自定义类名 confirmButtonClasses() return `el-button--primary $ this.confirmButtonClass `; , //添加取消按钮的自定义类名 cancelButtonClasses() return `$ this.cancelButtonClass `; , methods: // 关闭 getSafeClose() const currentId = this.uid; return () => this.$nextTick(() => if (currentId === this.uid) this.doClose(); ); ; , // 执行关闭事件 doClose() if (!this.visible) return; this.visible = false; this._closing = true; this.onClose && this.onClose(); messageBox.closeDialog(); // 解绑 // 如果是弹出框出来锁定body if (this.lockScroll) setTimeout(this.restoreBodyStyle, 200); this.opened = false; this.doAfterClose(); setTimeout(() => if (this.action) this.callback(this.action, this); ); , //点击弹框时,根据closeOnClickModal来是否可通过点击遮罩关闭 MessageBox handleWrapperClick() // 如果closeOnClickModal设置为true if (this.closeOnClickModal) //判断是否将取消(点击取消按钮)与关闭(点击关闭按钮或遮罩层、按下 ESC 键)进行区分 //如果区分则this.handleAction(‘close‘);否则this.handleAction(‘cancel‘); this.handleAction(this.distinguishCancelAndClose ? ‘close‘ : ‘cancel‘); , // 输入框键盘enter事件 handleInputEnter() if (this.inputType !== ‘textarea‘) // 确认 return this.handleAction(‘confirm‘); , handleAction(action) // 如果当前是this.$prompt并且点击了确认按钮并且没有验证通过 if (this.$type === ‘prompt‘ && action === ‘confirm‘ && !this.validate()) return; this.action = action; //判断beforeClose是否是函数,也就是用户是否定义了beforeClose函数 if (typeof this.beforeClose === ‘function‘) this.close = this.getSafeClose(); /** MessageBox 关闭前的回调,会暂停实例的关闭 function(action, instance, done),action 的值为‘confirm‘, ‘cancel‘或‘close‘;instance 为 MessageBox 实例,可以通过它访问实例上的属性和方法;done 用于关闭 MessageBox 实例 */ this.beforeClose(action, this, this.close); else //如果用户没有定义beforeClose,就调doClose直接关闭弹框 this.doClose(); , //该方法主要是用于用户在调用$prompt方法打开消息提示时,校验input输入框的值 validate() //$prompt方法即可打开消息提示,它模拟了系统的 prompt if (this.$type === ‘prompt‘) //获取用户自己定义的匹配模式 const inputPattern = this.inputPattern; //如果用户自己定义了匹配模式,并且用户输入校验不通过 if (inputPattern && !inputPattern.test(this.inputValue || ‘‘)) //显示用户自己定义的校验不通过时的提示信息;当用户未定义校验不通过的提示信息时,t(‘el.messagebox.error‘)输出提示:输入的数据不合法! this.editorErrorMessage = this.inputErrorMessage || t(‘el.messagebox.error‘); //这里主要是在校验不通过时,给input加上的类名中加上invalid,变成class="el-input__inner invalid" //通过.el-message-box__input input.invalidborder-color: #f56c6c;改变input的border为红色 addClass(this.getInputElement(), ‘invalid‘); return false; //输入框的校验函数;可以返回布尔值或字符串,若返回一个字符串, 则返回结果会被赋值给 inputErrorMessage const inputValidator = this.inputValidator; //如果校验函数存在 if (typeof inputValidator === ‘function‘) const validateResult = inputValidator(this.inputValue); //校验不通过,显示校验不通过的红色提示信息 if (validateResult === false) this.editorErrorMessage = this.inputErrorMessage || t(‘el.messagebox.error‘); addClass(this.getInputElement(), ‘invalid‘); return false; //若返回一个字符串, 则返回结果会被赋值给 inputErrorMessage if (typeof validateResult === ‘string‘) this.editorErrorMessage = validateResult; addClass(this.getInputElement(), ‘invalid‘); return false; //如果校验通过,则不显示错误提示,并删除类名invalid this.editorErrorMessage = ‘‘; removeClass(this.getInputElement(), ‘invalid‘); return true; , // 获取第一个聚焦元素 getFirstFocus() const btn = this.$el.querySelector(‘.el-message-box__btns .el-button‘); const title = this.$el.querySelector(‘.el-message-box__btns .el-message-box__title‘); return btn || title; , // 获取输入框元素 getInputElement() const inputRefs = this.$refs.input.$refs; return inputRefs.input || inputRefs.textarea; , watch: // 监听输入值得变化 inputValue: immediate: true,//立即触发 handler(val) //自定义函数 this.$nextTick(_ => if (this.$type === ‘prompt‘ && val !== null) this.validate(); ); , // 是否显示messagebox框 visible(val) if (val) this.uid++; // 如果是this.$alert或者this.$confirm if (this.$type === ‘alert‘ || this.$type === ‘confirm‘) this.$nextTick(() => // 确认按钮聚焦 this.$refs.confirm.$el.focus(); ); // document.activeElement -> 当前获取焦点的元素 this.focusAfterClosed = document.activeElement; messageBox = new Dialog(this.$el, this.focusAfterClosed, this.getFirstFocus()); // prompt if (this.$type !== ‘prompt‘) return; if (val) setTimeout(() => if (this.$refs.input && this.$refs.input.$el) this.getInputElement().focus(); , 500); else this.editorErrorMessage = ‘‘; removeClass(this.getInputElement(), ‘invalid‘); , mounted() this.$nextTick(() => if (this.closeOnHashChange) //如果需要,则在元素挂载之后,给window添加hashchange事件 window.addEventListener(‘hashchange‘, this.close); ); , beforeDestroy() // 组件销毁时移除hashchange事件 if (this.closeOnHashChange) window.removeEventListener(‘hashchange‘, this.close); setTimeout(() => messageBox.closeDialog(); //解绑 ); , data() return uid: 1, title: undefined, //MessageBox 标题 message: ‘‘, //MessageBox 消息正文内容 type: ‘‘, //消息类型,用于显示图标 iconClass: ‘‘, //自定义图标的类名,会覆盖 type customClass: ‘‘, //MessageBox 的自定义类名 showInput: false, //是否显示输入框 inputValue: null, //输入框的初始文本 inputPlaceholder: ‘‘, //输入框的占位符 inputType: ‘text‘, //输入框的类型 inputPattern: null, //输入框的校验表达式 inputValidator: null,//输入框的校验函数。可以返回布尔值或字符串,若返回一个字符串, 则返回结果会被赋值给 inputErrorMessage inputErrorMessage: ‘‘, //校验未通过时的提示文本 showConfirmButton: true, //是否显示确定按钮 showCancelButton: false, //是否显示取消按钮 action: ‘‘, //操作确认还是取消 confirmButtonText: ‘‘,//确定按钮的文本内容 cancelButtonText: ‘‘,//取消按钮的文本内容 confirmButtonLoading: false, //确认按钮的loading状态 cancelButtonLoading: false,//取消按钮的loading状态 confirmButtonClass: ‘‘,//确认按钮的类名 confirmButtonDisabled: false,//确认按钮是否禁用 cancelButtonClass: ‘‘,//取消按钮的类名 editorErrorMessage: null,//错误信息提示 callback: null,//回调函数 dangerouslyUseHTMLString: false,// 是否将 message 属性作为 HTML 片段处理 focusAfterClosed: null, isOnComposition: false, distinguishCancelAndClose: false//是否将取消(点击取消按钮)与关闭(点击关闭按钮或遮罩层、按下 ESC 键)进行区分 ; ; </script>
src/main.js
const defaults = title: null,//MessageBox 标题 message: ‘‘,//MessageBox 消息正文内容 type: ‘‘,//消息类型,用于显示图标 iconClass: ‘‘,//自定义图标的类名,会覆盖 type showInput: false, //是否显示输入框 showClose: true,//MessageBox 是否显示右上角关闭按钮 modalFade: true, lockScroll: true,//是否在 MessageBox 出现时将 body 滚动锁定 closeOnClickModal: true,//是否可通过点击遮罩关闭 MessageBox closeOnPressEscape: true,//是否可通过按下 ESC 键关闭 MessageBox closeOnHashChange: true,//是否在 hashchange 时关闭 MessageBox inputValue: null,//输入框的初始文本 inputPlaceholder: ‘‘,//输入框的占位符 inputType: ‘text‘,//输入框的类型 inputPattern: null, //输入框的校验表达式 inputValidator: null,//输入框的校验函数。可以返回布尔值或字符串,若返回一个字符串, 则返回结果会被赋值给 inputErrorMessage inputErrorMessage: ‘‘,//校验未通过时的提示文本 showConfirmButton: true,//是否显示确定按钮 showCancelButton: false,//是否显示取消按钮 confirmButtonPosition: ‘right‘, confirmButtonHighlight: false, cancelButtonHighlight: false, confirmButtonText: ‘‘, //确定按钮的文本内容 cancelButtonText: ‘‘,//取消按钮的文本内容 confirmButtonClass: ‘‘,//确定按钮的自定义类名 cancelButtonClass: ‘‘,//取消按钮的自定义类名 customClass: ‘‘,//MessageBox 的自定义类名 beforeClose: null,//MessageBox 关闭前的回调,会暂停实例的关闭 dangerouslyUseHTMLString: false,//是否将 message 属性作为 HTML 片段处理 center: false,//是否居中布局 roundButton: false,//是否使用圆角按钮 distinguishCancelAndClose: false//是否将取消(点击取消按钮)与关闭(点击关闭按钮或遮罩层、按下 ESC 键)进行区分 ; import Vue from ‘vue‘; import msgboxVue from ‘./main.vue‘; import merge from ‘element-ui/src/utils/merge‘; import isVNode from ‘element-ui/src/utils/vdom‘; //创建MessageBox的构造器,包含msgboxVue组件选项的对象作为Vue.extend的参数,返回一个VueComponent类,VueComponent类是Vue类的子类 //Vue.extend是一个类构造器,用来创建一个子类vue并返回构造函数,而Vue.component它的任务是将给定的构造函数与字符串ID相关联,以便Vue.js可以在模板中接收它。 const MessageBoxConstructor = Vue.extend(msgboxVue); let currentMsg, instance; let msgQueue = []; const defaultCallback = action => if (currentMsg) let callback = currentMsg.callback; if (typeof callback === ‘function‘) if (instance.showInput) callback(instance.inputValue, action); else callback(action); if (currentMsg.resolve) // 点击确定或者去下关闭按钮时,在此处调对应的方法进行处理 if (action === ‘confirm‘) //执行确认后的回调方法 if (instance.showInput) currentMsg.resolve( value: instance.inputValue, action ); else currentMsg.resolve(action); else if (currentMsg.reject && (action === ‘cancel‘ || action === ‘close‘)) //执行取消和关闭后的回调方法 currentMsg.reject(action); ; const initInstance = () => //instance为messageBox的实例 instance = new MessageBoxConstructor( el: document.createElement(‘div‘) ); instance.callback = defaultCallback; ; const showNextMsg = () => if (!instance) // 调用initInstance初始化实例,返回messageBox的实例对象 initInstance(); instance.action = ‘‘; if (!instance.visible || instance.closeTimer) if (msgQueue.length > 0) currentMsg = msgQueue.shift(); //将用户设置的属性和方法挂载到messageBox的实例对象instance上去 let options = currentMsg.options; for (let prop in options) if (options.hasOwnProperty(prop)) instance[prop] = options[prop]; //当用户未设置callback时,将defaultCallback赋值给instance.callback if (options.callback === undefined) instance.callback = defaultCallback; let oldCb = instance.callback; instance.callback = (action, instance) => oldCb(action, instance); showNextMsg(); ; if (isVNode(instance.message)) instance.$slots.default = [instance.message]; instance.message = null; else delete instance.$slots.default; // 默认设置为true [‘modal‘, ‘showClose‘, ‘closeOnClickModal‘, ‘closeOnPressEscape‘, ‘closeOnHashChange‘].forEach(prop => if (instance[prop] === undefined) instance[prop] = true; ); document.body.appendChild(instance.$el); Vue.nextTick(() => instance.visible = true; ); ; const MessageBox = function (options, callback) if (Vue.prototype.$isServer) return; if (typeof options === ‘string‘ || isVNode(options)) options = message: options ; // 第二个参数设置为title if (typeof arguments[1] === ‘string‘) options.title = arguments[1]; else if (options.callback && !callback) callback = options.callback; if (typeof Promise !== ‘undefined‘) return new Promise((resolve, reject) => // eslint-disable-line // options合并默认的所有参数和用户设置的参数 msgQueue.push( options: merge(, defaults, MessageBox.defaults, options), callback: callback, resolve: resolve, reject: reject ); showNextMsg(); ); else msgQueue.push( options: merge(, defaults, MessageBox.defaults, options), callback: callback ); showNextMsg(); ; MessageBox.setDefaults = defaults => MessageBox.defaults = defaults; ; //this.$alert方法 MessageBox.alert = (message, title, options) => //如果title的类型为object时,用户可能没传title,则将title的值赋值给options if (typeof title === ‘object‘) options = title; title = ‘‘; else if (title === undefined) title = ‘‘; //合并用户传的参数,并调用MessageBox方法 return MessageBox(merge( title: title, message: message, $type: ‘alert‘, closeOnPressEscape: false, closeOnClickModal: false , options)); ; //this.$confirm方法,分析同MessageBox.alert方法 MessageBox.confirm = (message, title, options) => if (typeof title === ‘object‘) options = title; title = ‘‘; else if (title === undefined) title = ‘‘; return MessageBox(merge( title: title, message: message, $type: ‘confirm‘, showCancelButton: true , options)); ; //this.$prompt方法,分析同MessageBox.alert方法 MessageBox.prompt = (message, title, options) => if (typeof title === ‘object‘) options = title; title = ‘‘; else if (title === undefined) title = ‘‘; return MessageBox(merge( title: title, message: message, showCancelButton: true, showInput: true, $type: ‘prompt‘ , options)); ; // 关闭 MessageBox.close = () => instance.doClose(); instance.visible = false; msgQueue = []; currentMsg = null; ; export default MessageBox; export MessageBox ;
以上是关于element message-box源码的主要内容,如果未能解决你的问题,请参考以下文章
Selenium Xpath元素无法定位 NoSuchElementException: Message: no such element: Unable to locate element(代码片段
js代码片段: utils/lcoalStorage/cookie
TP5报如下的错误 Indirect modification of overloaded element of thinkpaginatorCollection has no effect(代码片段
maven web项目的web.xml报错The markup in the document following the root element must be well-formed.(代码片段