原理: 通过vue提供的render, createVNode方法将vue组件转为dom挂载到指定的元素下
import MaterialFolderDialog from "./MaterialFolderDialog.vue"
import { render, createVNode, nextTick } from "vue"
export function open(data: any) {
let vNode = null
const container = document.createElement("div")
// 移除组件
const doClose = () => {
console.log("close...")
vNode = null
render(null, container)
container.remove()
}
// createVNode 支持以下6个参数
// type: VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT
// props?: (Data & VNodeProps) | null 子组件接收的值
// children?: unknown,
// patchFlag?: number,
// dynamicProps?: string[] | null,
// isBlockNode?: boolean
// type: 表示要创建的节点的类型。可以是:
// 一个字符串,表示一个 HTML 标签(例如 'div')。
// 一个组件对象,表示一个 Vue 组件。
// 一个异步组件的工厂函数。
// props: (可选)表示要传递给该节点的属性和事件监听器。这是一个对象。
// children: (可选)表示子节点。可以是一个字符串(表示文本节点),一个数组(表示多个子节点),或者一个对象(表示具名插槽)。
vNode = createVNode(MaterialFolderDialog, { ...data, doClose })
nextTick(() => {
render(vNode, container) // 将组件的vNode挂载到container节点下
console.log(container) // dom
document.body.appendChild(container) // 挂载到body
})
}
MaterialFolderDialog组件
<template>
<el-dialog v-model="visible" title="新建文件夹" width="600px" @opened="open" @close="close">{{ text }} </el-dialog>
</template>
<script setup lang="ts">
import { ref } from "vue"
import { ElDialog } from "element-plus"
const props = defineProps({
text: {
type: String,
default: "测试",
},
doClose: {
type: Function,
default: () => null,
},
})
const visible = ref(true)
const open = () => {
console.log(props.text)
}
const close = () => {
props.doClose()
}
</script>
<style scoped lang="scss"></style>
评论列表
已有0条评论