动态创建弹框el-dialog

37 篇文章 0 订阅
17 篇文章 0 订阅

相信大家在页面中写了很多基于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

<template>
  <el-dialog :title="title" :visible.sync="visible" :close-on-click-modal="false">
    <div>{{text}}</div>
    <div style="margin-top: 10px;">{{newLineText}}</div>
    <div slot="footer" class="dialog-footer">
      <el-button type="primary" @click="onCallback(true)" v-if="confirmShow">{{confirmText}}</el-button>
      <el-button  @click="onCallback(false)" v-if="cancelShow">{{cancelText}}</el-button>
    </div>
  </el-dialog>
</template>

<script>
  export default {
    data () {
      return {
        title: '提示',
        text: '确定该操作?',
        confirmText: '确定',
        cancelText: '取消',
        confirmShow: 1,
        cancelShow: 1,
        newLineText: ''
      }
    },
    methods: {
    }
  }
</script>

3、第三步直接使用

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

 小部件

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值