弾枠el-dialogを動的に作成する
5522 ワード
皆さんはページの中でel-dialogに基づく弾枠をたくさん書いたと信じています.特に弾枠が多い場合、肥大化していて、後期のメンテナンスに不利です.似たような弾枠機能があります.コピーして貼るのが面倒です.名前を変えなければなりません.次はまだいい方法があります.データを転送して、データを返すだけでいいです.次は直接コードを貼ります.
dialog.js
1.このjsファイルはmainに直接あります.js導入で終わりだ
2.ステップ2で、ポップアップページファイル名@confirmを新規作成します.vue
3、第三歩直接使用
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
{
{text}}
{
{newLineText}}
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')
}
},