背景
开发中,有时候封装组件希望能够通过方法来动态创建,能够更简洁,方便的在其他地方创建实例,特别对于较为复杂的条件判断动态创建渲染实例,使用方法逻辑判断更加利于开发维护。比如一些提示类的弹窗,登录弹窗等场景。
Vue
中的extend,下面是Vue2的官方介绍
操作实例
- 编写一个弹窗组件
DialogTest.vue
,使用
<template>
<div class="test-dialog-wrap">
<el-dialog
title="测试"
:visible.sync="dialogVisible"
custom-class="test-dialog"
:close-on-click-modal="false"
:close-on-press-escape="false"
v-loading="isLoading"
>
<div class="test-contain" ref="testRef" id="testRef"></div>
//设置插槽,自定义内容
<slot></slot>
</el-dialog>
</div>
</template>
<script>
export default {
props: {
value: {
type: Boolean,
default: false,
},
isLoading: {
type: Boolean,
default: true,
},
width: {
type: Number,
default: 920,
},
height: {
type: Number,
default: 518,
},
},
data() {
return {};
},
computed: {
dialogVisible: {
get() {
return this.value;
},
set(val) {
this.$emit("update:value", val);
},
},
},
};
</script>
<style scoped lang="scss">
.test-dialog-wrap {
/deep/.test-dialog {
border-radius: 20px;
background-color: transparent;
width: fit-content;
.el-dialog__header {
background-color: rgba(172, 208, 236, 1);
border-radius: 20px 20px 0px 0px;
}
.el-dialog__body {
padding: 15px 20px;
.xgplayer video {
object-fit: cover;
}
}
.video-contain {
width: 100%;
/* height: 54vh; */
min-height: 450px;
/* overflow: auto; */
&::-webkit-scrollbar {
width: 10px;
height: 10px;
background-color: transparent;
}
&::-webkit-scrollbar-thumb {
height: 100px;
border-radius: 5px;
background-color: rgba(144, 147, 153, 0.3);
}
&::-webkit-scrollbar-track {
border-radius: 5px;
border-color: transparent;
margin: 1px;
}
}
}
}
</style>
- 创建实例方法
import DialogTest from "./DialogTest.vue"
export funtion createDialog(slotVNode = null){
const dynDialogCreate = Vue.extend(DialogTest)
let instance = new dynDialogCreate({
propsData:{
value:true,
isLoading: false,
}
})
//挂载实例
instance.$mount()
document.body.appendChild(instance.$el);
// 添加插槽内容到已挂载的元素中
if (slotVNode) {
instance.$slots.default = [slotVNode];
}
// 当对话框关闭时,从 DOM 中移除它
instance.$on("update:value", (val) => {
if (!val) {
instance.$destroy();
document.body.removeChild(instance.$el);
instance = null; // 重置实例
}
});
//调用
//如果想在使用插槽
const vnode = this.$createElement("div", { class: "custom-content" }, [
"这里是自定义内容,可以是任意合法的 HTML 字符串或 VNode",
]);
createDialog(vnode)
总结
extend
创建的Vue的子类,其可用属性可查看FunctionalComponentOptions接口,