实现页面不同层级内容解耦,使代码更清晰易维护。一个比较常见的场景是关闭表单时需要清空表单内容(element-ui dialog有个destroy-on-close属性,但是我使用时没有生效,也不知道为啥)。以element-ui dialog为例,其他库同理。
import Vue from 'vue';
import { Message } from 'element-ui';
/**
* @param {Object} component - 组件,需定义handleSubmit方法,并在方法内执行$emit('submit',[params])
* @param {string} title - dialog标题
* @param {Object} props - 传递给组件的数据
* @param {Function} submit - 点击确认的回调函数,参数为组件的handleSubmit函数中$emit参数
*/
export default function DialogCall(component, title, props, submit) {
let instance;
const VueClass = Vue.extend({
data() {
return {
visible: false,
loading: false,
};
},
mounted() {
this.visible = true;
},
render(h) {
return h(
'el-dialog',
{
props: { 'visible': this.visible, title, 'close-on-click-modal': false, 'close-on-press-escape': false },
on: {
'update:visible': (value) => {
this.visible = value;
},
'closed': () => {
instance.$el.remove();
instance.$destroy();
},
},
},
[
h(component, {
props,
on: {
submit: async (event) => {
if (typeof submit === 'function') {
this.loading = true;
const bool = await submit(event);
this.loading = false;
if (bool !== false) {
this.visible = false;
}
} else {
Message.error('参数submit不是一个方法');
}
},
close: ()=> (this.visible = false)
},
ref: 'content',
}),
h('template', { slot: 'footer' }, [
h(
'el-button',
{
props: { size: 'medium' },
on: {
click: () => {
const callback = this.$refs.content.handleCancel;
if (typeof callback === 'function') {
callback();
} else {
this.visible = false;
}
},
},
},
'取消'
),
h(
'el-button',
{
props: { size: 'medium', type: 'primary', loading: this.loading },
on: {
click: () => {
const callback = this.$refs.content.handleSubmit;
if (typeof callback === 'function') {
callback();
} else {
Message.error('dialog默认插槽组件未定义handleSubmit方法');
}
},
},
},
'确认'
),
]),
]
);
},
});
instance = new VueClass();
const div = document.createElement('div');
document.body.append(div);
instance.$mount(div);
}