2020-04-26 mixin

2020-04-26  本文已影响0人  Allan要做活神仙
image.png
import dialogMix from 'src/common/vue/mixins/dialogMix';
import {cmpInfo} from './components/main';

// 当前存在的弹框
let activeDialogs = [];
// 弹框队列 通过下标查找当前弹框层
// 数据示例[[],[],[]]
let dialogQueue = [];

/**
 * @description: 创建组件
 * @param {pos} 弹框层级
 */
let createComponent = (pos) => {
    const opt = dialogQueue[pos].shift();
    let Dialog = Vue.extend(cmpInfo[opt.name]);
    // 当前实例
    let instance;
    // 上个实例不存在/不同实例 创建
    const preDialog = activeDialogs.length && activeDialogs[activeDialogs.length - 1];

    if (!preDialog || opt.name !== preDialog.name) {
        instance = new Dialog({
            data() {
                return {
                    ...opt,
                };
            },
            mixins: [dialogMix],
            watch: {
                isShow(val) {
                    if (!val) {
                        // 关闭逻辑处理
                        activeDialogs.pop();
                        instance && instance.$nextTick(() => {
                            instance.$destroy();
                            instance = null;
                            if (dialogQueue[pos] && dialogQueue[pos].length) {
                                createComponent(pos);
                            } else {
                                dialogQueue.pop();
                            }
                        });
                    }
                },
            },
        });
        document.body.appendChild(instance.$mount().$el);
        instance.open();
        activeDialogs.push(instance);
    } else {
        // 同一个实例 更新数据
        Object.assign(preDialog, opt);
    }
};

const install = (Vue) => {
    // 注册全局方法
    Vue.prototype.$dialog = (options, newLayer = true) => {
        const len = dialogQueue.length;
        if (typeof options === 'string') {
            options = [
                {
                    name: options,
                },
            ];
        } else if (!(options instanceof Array)) {
            options = [options];
        }

        // 层叠创建新弹框/追加但当前没有弹框也创建
        if (newLayer || !len) {
            dialogQueue[len] = options;
            createComponent(dialogQueue.length - 1);
        } else {
            // 追加弹框
            dialogQueue[len - 1] = dialogQueue[len - 1].concat(options);
        }
    };
    // 关闭所有弹框
    Vue.prototype.$dialog.closeAll = () => {
        dialogQueue.length = 0;
        activeDialogs.forEach((item) => {
            item.close();
        });
        activeDialogs.length = 0;
    };
};
export default install;

上一篇下一篇

猜你喜欢

热点阅读