弾枠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.ステップ2で、ポップアップページファイル名@confirmを新規作成します.vue



  export default {
    data () {
      return {
        title: '  ',
        text: '     ?',
        confirmText: '  ',
        cancelText: '  ',
        confirmShow: 1,
        cancelShow: 1,
        newLineText: ''
      }
    },
    methods: {
    }
  }


3、第三歩直接使用
      async opt () {
        let ret = await this.$dialog.Confirm({text: '    ?'})
        if (ret) {
          console.log(ret,'Dayer')
        }
      },