有时候,一个页面会有多个弹窗,而且不一定会触发,如果使用Vue.component的方法,那就要在html中提前书写,且需要多个属性去维护弹窗的显示与隐藏,那么,它来了它来了,它带着代码走来了
创建一个容纳组件的容器
function generateDialogContainer() {
let stap = (new Date()).getTime();
$('body').append(`<div id="ymDialog${stap}"></div>`);
return `ymDialog${stap}`;
}
声明组件的基本结构(函数返回值形态便于传入额外的渲染参数)
function generateDialogTemplate(options) {
let tpl = {
template: `
<el-dialog :title="title"
:visible.sync="dialogShow"
custom-class=""
append-to-body
>
${options.template} // 相当于slot,可以传入自定义内容
<div slot="footer" class="dialog-footer">
<el-button @click="dialogShow = false">取 消</el-button>
<el-button type="primary" @click="confirmEvent">确 定</el-button>
</div>
</el-dialog>
`,
data: {
// 不要写成函数形态,下面会对其操作
},
created() {
},
props: {
title: String
},
watch: {
},
mounted() {
},
methods: {
}
}
// 把参数中的data和methods与当前合并,相当于mixin
if (!!options.data) {
Object.keys(options.data).forEach(item => {
tpl.data[item] = options.data[item]
})
}
const temp = tpl.data
tpl.data = function () {
return temp
}
if (!!options.methods) {
Object.keys(options.methods).forEach(item => {
tpl.methods[item] = options.methods[item]
})
}
return tpl
}
调用组件
// initData 第一次打开弹窗时默认渲染数据,可通过options或props传入
// callback 弹窗点击确定后触发
// 函数参数随意自定义
function openDialog(initData,callback) {
// 用于存储组件对象,可通过该对象直接操作组件的data或者调用组件的methods
// object类型,为了应对ajax请求等 异步操作
let tagDialog = {
obj: null
}
// 初始化组件参数
let options = {
template: '<button @click="add">{{total}}<button>',
data: {
total: 0
},
methods: {
add() {
this.total += 1
}
}
};
// 传入组件的props
let props = {
title: "测试"
};
// 生成弹窗的容器
let id = generateDialogContainer();
// 初始化组件返回模板
let tpl = generateDialogTemplate(options);
// 使用Vue构造器创建一个“子类”
let judy = Vue.extend(tpl);
// 实例化“子类”并把它挂在dom上
tagDialog.obj = new judy({
propsData: props,
}).$mount(`#${id}`);
return tagDialog
}
调用
let dialog = null
function callback(res) {
console.log(res)
}
let initData = [1,2,3]
if(!dialog) {
dialog = openDialog(initData,callback)
}else {
// 可直接通过组件对象操作
dialog.obj.total = 10
dialog.obj.add()
}