动态创建弹框el-dialog

相信大家在页面中写了很多基于el-dialog的弹框,尤其是弹框比较多时,显得很臃肿,不利于后期维护,还有一些相似的弹框功能让你复制粘贴感觉很麻烦还要换个名字,下面我有个还行的方法动态创建,只需要传数据,然后返回数据就可以了,下面直接贴代码哈哈

dialog.js

import Vue from 'vue'
function snake2Camel(str, capLower) {
    let s = str.replace(/[-_](\w)/g, function (x) {
        return x.slice(1).toUpperCase()
    })
    s = s.replace(/^\w/, function (x) {
        return capLower ? x.toLowerCase() : x.toUpperCase()
    })
    return s
}

function camel2Snake(str) {
    return str.replace(/([A-Z])/g, '-$1').toLowerCase()
}

const dialogsContext = require.context('../', true, /@([a-zA-Z\-0-9]+)\.vue$/)
const dialogs = dialogsContext.keys().reduce((views, key) => {
    const fileName = key.match(/@([a-zA-Z\-0-9]+)\.vue$/i)[1]
    if (!fileName) return views
    let componentName = camel2Snake(fileName)
    let clsName = snake2Camel(componentName)
    return Object.assign(views, { [clsName]: dialogsContext(key) })
}, {})

const createDialog = function (temp, data, callback) {
    let opt = {
        data,
        callback
    }
    let component = Object.assign({}, temp)
    let initData = {
        visible: true
    }
    Object.assign(initData, component.data())
    opt.data && Object.assign(initData, JSON.parse(JSON.stringify(opt.data)))
    component.data = function () {
        return initData
    }
    let DialogC = Vue.extend(component)
    let dialog = new DialogC()
    // 关闭事件
    let _onClose = dialog.$options.methods.onClose
    dialog.$watch('visible', function (n, o) {
        dialog === false && dialog.onClose()
    })
    dialog.onClose = function () {
        dialog.$destroy()
        _onClose && _onClose.call(dialog)
        document.body.removeChild(dialog.$el)
    }
    // 回调事件
    let _onCallback = dialog.$options.methods.onCallback
    dialog.onCallback = function (...arg) {
        try {
            _onCallback && _onCallback()
            if (callback && typeof callback === 'function') {
                callback.call(this, ...arg, dialog)
            }
        } catch (e) {
            console.log(e)
        }
    }
    dialog.$mount()
    dialog.$watch('visible', function (n, o) {
        dialog === false && dialog.onClose()
    })
    document.body.appendChild(dialog.$el)
}

function createDialogAsync(temp, data) {
    return new Promise(function (resolve, reject) {
        let opt = {
            data
        }
        let component = Object.assign({}, temp)
        let initData = {
            visible: true
        }
        Object.assign(initData, component.data())
        opt.data && Object.assign(initData, JSON.parse(JSON.stringify(opt.data)))
        console.log(initData, 'init')
        component.data = function () {
            return initData
        }
        let DialogC = Vue.extend(component)
        let dialog = new DialogC()
        // 关闭事件
        let _onClose = dialog.$options.methods.onClose
        dialog.onClose = function () {
            resolve()
            dialog.$destroy()
            _onClose && _onClose.call(dialog)
            document.body.removeChild(dialog.$el)
        }
        // 回调事件
        let _onCallback = dialog.$options.methods.onCallback
        dialog.onCallback = function (...arg) {
            try {
                _onCallback && _onCallback()
                resolve(...arg)
                dialog.$destroy()
                _onClose && _onClose.call(dialog)
                document.body.removeChild(dialog.$el)
            } catch (e) {
                console.log(e)
            }
        }
        dialog.$mount()
        dialog.$watch('visible', function (n, o) {
            dialog === false && dialog.onClose()
        })
        document.body.appendChild(dialog.$el)
    })
}

function init(values) {
    let dialogComponents = {}
    if (!values) return
    Object.keys(values).forEach((name) => {
        let ComponentContext = values[name].default
        dialogComponents[name] = function (data, callback) {
            if (callback && typeof callback === 'function') {
                return createDialog.call(this, ComponentContext, data, callback)
            }
            return createDialogAsync.call(this, ComponentContext, data)
        }
    })
    return dialogComponents
}

Vue.prototype.$dialog = init(dialogs)

1.这个js文件直接在main.js引入就完事了

2.第二步新建一个弹框页面文件名@confirm.vue




3、第三步直接使用

      async opt () {
        let ret = await this.$dialog.Confirm({text: '确定提交?'})
        if (ret) {
          console.log(ret,'Dayer')
        }
      },

 

你可能感兴趣的:(JavaScript,vue,es6,el-dialog,动态创建弹框,element,async,await)