Vue中的extend,动态创建实例

背景

开发中,有时候封装组件希望能够通过方法来动态创建,能够更简洁,方便的在其他地方创建实例,特别对于较为复杂的条件判断动态创建渲染实例,使用方法逻辑判断更加利于开发维护。比如一些提示类的弹窗,登录弹窗等场景。

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接口,

猜你喜欢

转载自blog.csdn.net/weixin_43914605/article/details/140806996