<template> <transition name="msgbox-fade"> <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']"> <div class="el-message-box__header" v-if="title !== null"> <div class="el-message-box__title"> <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__container"> <div :class="['el-message-box__status', icon]" v-if="icon && !center && message !== ''"> </div> <div class="el-message-box__message" v-if="message !== ''"> <slot> <p v-if="!dangerouslyUseHTMLString">{{ message }}</p> <p v-else v-html="message"></p> </slot> </div> </div> <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 }, lockScroll: { default: true }, showClose: { type: Boolean, default: true }, closeOnClickModal: { default: true }, closeOnPressEscape: { default: true }, closeOnHashChange: { default: true }, center: { default: false, type: Boolean }, roundButton: { default: false, type: Boolean } }, components: { ElInput, ElButton }, computed: { icon() { const { type, iconClass } = this; 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(); // 瑙g粦 if (this.lockScroll) { setTimeout(this.restoreBodyStyle, 200); } this.opened = false; this.doAfterClose(); setTimeout(() => { if (this.action) this.callback(this.action, this); }); }, handleWrapperClick() { if (this.closeOnClickModal) { this.handleAction(this.distinguishCancelAndClose ? 'close' : 'cancel'); } }, handleInputEnter() { if (this.inputType !== 'textarea') { return this.handleAction('confirm'); } }, handleAction(action) { if (this.$type === 'prompt' && action === 'confirm' && !this.validate()) { return; } this.action = action; if (typeof this.beforeClose === 'function') { this.close = this.getSafeClose(); this.beforeClose(action, this, this.close); } else { this.doClose(); } }, validate() { if (this.$type === 'prompt') { const inputPattern = this.inputPattern; if (inputPattern && !inputPattern.test(this.inputValue || '')) { this.editorErrorMessage = this.inputErrorMessage || t('el.messagebox.error'); addClass(this.getInputElement(), 'invalid'); return false; } 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; } if (typeof validateResult === 'string') { this.editorErrorMessage = validateResult; addClass(this.getInputElement(), 'invalid'); return false; } } } 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; }, handleClose() { this.handleAction('close'); } }, watch: { inputValue: { immediate: true, handler(val) { this.$nextTick(_ => { if (this.$type === 'prompt' && val !== null) { this.validate(); } }); } }, visible(val) { if (val) { this.uid++; if (this.$type === 'alert' || this.$type === 'confirm') { this.$nextTick(() => { this.$refs.confirm.$el.focus(); }); } 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.addEventListener('hashchange', this.close); } }); }, beforeDestroy() { if (this.closeOnHashChange) { window.removeEventListener('hashchange', this.close); } setTimeout(() => { messageBox.closeDialog(); }); }, data() { return { uid: 1, title: undefined, message: '', type: '', iconClass: '', customClass: '', showInput: false, inputValue: null, inputPlaceholder: '', inputType: 'text', inputPattern: null, inputValidator: null, inputErrorMessage: '', showConfirmButton: true, showCancelButton: false, action: '', confirmButtonText: '', cancelButtonText: '', confirmButtonLoading: false, cancelButtonLoading: false, confirmButtonClass: '', confirmButtonDisabled: false, cancelButtonClass: '', editorErrorMessage: null, callback: null, dangerouslyUseHTMLString: false, focusAfterClosed: null, isOnComposition: false, distinguishCancelAndClose: false }; } }; </script>