`

vuejs message-box

 
阅读更多
<template>
    <transition name="messagebox-wrapper-fade">
        <div class="xigua-modal-dialog message-box-wrapper"
            :class="{'xigua-modal-hidden': !showModal}"
            v-show="visible"
            @click.stop="handleWrapperClick">
            <!-- start slot name=message-box -->
            <slot name="message-box">
                <div class="message-box" :class="[customDefaultClass, messageBoxCustom]"  @click.stop="">
                    <!-- start slot name=header-wrapper -->
                    <slot name="header-wrapper">
                        <div class="xigua-modal-header" v-if="title !== undefined || true">
                            <slot name="title">
                                <button type="button" class="close" @click.stop="handleAction('cancel')">×</button>
                                <h3 class="xigua-modal-title">{{ title }}</h3>
                            </slot>
                        </div>
                    </slot>
                    <!-- end slot name=header-wrapper -->

                    <!-- start slot name=content-wrapper -->
                    <slot name="content-wrapper">
                        <div class="message-box-content">
                            <!-- start slot name=content -->
                            <slot name="content">
                                <div class="message-box-content-alert-text" v-if="type == 'alert' || type == 'msgbox'">{{ message }}</div>
                                <div class="message-box-content-confirm-text" v-if="type == 'confirm'">{{ message }}</div>
                                <!-- start slot name=prompt -->
                                <slot name="prompt">
                                    <div class="message-box-content-prompt" v-if="type == 'prompt'">
                                        <div class="message-box-content-prompt-title">{{message}}</div>
                                        <!-- start slot name=prompt-content -->
                                        <slot name="prompt-content">
                                            <div class="message-box-content-prompt-content" >
                                                <input class="message-box-content-prompt-content-input" autofocus="autofocus" v-model="inputValue" @keyup.enter="handleAction('confirm')"  :placeholder="inputPlaceholder"></input>
                                                <div class="message-box-content-prompt-content-errMessage" :class="errorMessageClass">{{inputErrorMessage}}</div>
                                            </div>
                                        </slot>
                                        <!-- end slot name=prompt-content -->
                                    </div>
                                </slot>
                                <!-- end slot name=prompt -->
                                <slot name="self"></slot>
                            </slot>
                            <!-- end slot name=content -->
                        </div>
                    </slot>
                    <!-- end slot name=content-wrapper -->

                    <!-- start slot name=btns-wrapper -->
                    <slot name="btns-wapper">
                        <div class="dialog-footer message-box-btns">
                            <slot name="btns">
                                <button
                                    class="message-box-confirm"
                                    :class="[ confirmButtonClass, buttonDisabledClass ]"
                                    v-if="showConfirmButton"
                                    :disabled="confirmBtnDisabled" @click.stop="handleAction('confirm')">{{ confirmButtonText }}</button>
                                <button :class="[ cancelButtonClass ]" v-if="showCancelButton" @click.stop="handleAction('cancel')">{{ cancelButtonText }}</button>
                            </slot>
                        </div>
                    </slot>
                    <!-- end slot name=btns-wrapper -->
                </div>
            </slot>
            <!-- end slot name=message-box -->
        </div>
    </transition>
</template>
<script>
    import {
        addClass,
        removeClass
    } from 'wind-dom/src/class';
    let typeMap = {
        success: 'circle-check',
        info: 'information',
        warning: 'warning',
        error: 'circle-cross'
    };
    export default {
        data() {
            return {
                title: undefined,
                message: '',
                type: '',
                closeOnClickModal: true,
                closeOnPressEscape: true,

                customDefaultClass: 'message-box-default',
                customAnimaiClass: 'message-box-enter',

                inputValue: '',
                inputPlaceholder: '',
                inputPattern: null,
                inputErrorMessage: '输入有误',
                errorMessageClass: 'hidden',

                showConfirmButton: true,
                showCancelButton: true,
                showModal: true,
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                confirmButtonClass: 'btn btn-primary',
                cancelButtonClass: 'btn btn-default',

                visible: false,
                lockScroll: true,
                resolve: null,
                reject: null
            };
        },
        props: {
            componentTitle: {

            }
        },
        mounted () {
            let that = this;
            if (that.lockScroll) {
                document.body.style.overflow = 'hidden';
            }
        },
        computed: {
            messageBoxCustom () {
                let that = this;
                return that.visible ? that.customAnimaiClass : '';
            },
            buttonDisabledClass () {
                let that = this;
                return that.confirmBtnDisabled ? 'btn-disabled' : '';
            },
            inputWrong () {
                let that = this;
                if (!that.inputPattern) {
                    return false;
                }
                return !that.inputPattern.test(that.inputValue);
            },
            confirmBtnDisabled () {
                let that = this;
                if (that.type === 'prompt' && that.inputPattern && that.inputWrong) {
                    return true;
                } else {
                    return false;
                }
            }
        },
        methods: {
            modalClose () {
                let that = this;
                if (!closeOnClickModal) {
                    return;
                }
                that.close ();
            },
            close () {
                this.closed = true;
                this.visible = false;
                this.$el.addEventListener('transitionend', this.destroyElement);
            },
            destroyElement() {
                if (this.lockScroll) {
                    document.body.style.overflow = '';
                }
                this.$el.removeEventListener('transitionend', this.destroyElement);
                this.$destroy(true);
                this.$el.parentNode.removeChild(this.$el);
            },
            doClose() {
                this.visible = false;
                this._closing = true;
                this.onClose && this.onClose();
                if (this.lockScroll) {
                    setTimeout(() => {
                        if (this.modal && this.bodyOverflow !== 'hidden') {
                            document.body.style.overflow = this.bodyOverflow;
                            document.body.style.paddingRight = this.bodyPaddingRight;
                        }
                        this.bodyOverflow = null;
                        this.bodyPaddingRight = null;
                    }, 200);
                }
                this.opened = false;
                if (!this.transition) {
                    this.doAfterClose();
                }
            },
            handleWrapperClick() {
                if (this.closeOnClickModal) {
                    this.handleAction('cancel');
                }
            },

            handleAction(action) {
                if (action === 'confirm' && this.confirmBtnDisabled) {
                    return;
                }
                this.setPromise(action);
                this.close();
            },

            setPromise (action) {
                let that = this;
                if (!that.reject && !that.resolve) {
                    if (that.callback) {
                        callback();
                    } else {
                        return;
                    }
                }
                let type = that.type;
                let message = {
                    type: action
                };
                if (type === 'alert' || action === 'confirm'){
                    if (type === 'prompt') {
                        message.value = that.inputValue;
                    } else {
                        message.value = true;
                    }
                    that.resolve(message);
                } else if (action === 'cancel') {
                    message.value = false;
                    that.reject(message);
                }
            }
        },
        watch: {
            inputWrong (val) {
                let that = this;
                that.errorMessageClass = !val ? 'hidden' : 'show';
            },
            visible (val) {
                if (this.type === 'alert' || this.type === 'confirm') {
                    this.$nextTick(() => {
                        this.$el.querySelector('button.message-box-confirm').focus();
                    });
                }
                if (this.type !== 'prompt') return;
                if (val) {
                    setTimeout(() => {
                        this.$el.querySelector('input').focus();
                    }, 500);
                } else {
                    this.editorErrorMessage = '';
                    removeClass(this.$el.querySelector('input'), 'invalid');
                }
            }
        },

    };
</script>

 

 

export default (Vue) => {
    let MessageBoxConstructor = Vue.extend(require('./message.box.vue'));

    let instance;

    let defaultCallback = (action) => {
        instance.resolve({
            value: instance.vm.inputValue,
            action: action
        });
    };
    let MessageBox = function (options) {
        options = options || {};
        if (typeof options === 'string') {
            options = {
                message: options
            };
        }
        let userOnClose = options.onClose;

        options.onClose = function () {
            MessageBox.close(id, userOnClose);
        };

        instance = new MessageBoxConstructor({
            data: options
        });
        instance.vm = instance.$mount();
        document.body.appendChild(instance.vm.$el);
        instance.vm.visible = true;
        instance.dom = instance.vm.$el;
        return instance.vm;
    };
    ['alert', 'confirm', 'prompt', 'msgbox'].forEach(type => {
        let proxy = '$' + type;
        MessageBox[proxy] = (options) => {
            options.type = type;
            let promise = new Promise(function (resolve, reject) {
                options.resolve = resolve;
                options.reject = reject;
            });
            MessageBox(options);
            return promise;
        };
        Vue.prototype[proxy] = MessageBox[proxy];
    });
    return MessageBoxConstructor;
};

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics