vue命令式组件
命令式通过 API 来调用组件,类似cube-ui
里面的create-api,包括 element-plus
里面的一些弹出式组件都支持命令式调用.
这里我们通过 vue 里面暴露的h
和render
方法. h函数官网有介绍. render 函数是 vue 底层的一个 api 它是将虚拟节点渲染到真实 DOM 上的.
这里的 ElDialog 引入的是 element-plus 的组件.当然也可以引入自定义的组件.这里使用 firstElementChild 的原因是 render 会将组件渲染到 div 里面.
// dialog.js
import { h, render } from 'vue'
import { ElDialog } from 'element-plus'
export function useElDialog(props = {}, slots = {}) {
const vnode = h(
ElDialog,
{
onClose,
...props,
},
slots
)
const container = document.createElement('div') // 创建一个新的 div 容器
render(vnode, container) // 在新的容器中渲染 vnode
const dialogElement = container.firstElementChild // 获取渲染后的第一个子元素
document.body.appendChild(dialogElement) // 将渲染的元素添加到 document.body
function onClose() {
render(null, container) // 在容器中卸载组件
document.body.removeChild(dialogElement) // 从 document.body 移除渲染的元素
}
return onClose
}
使用
const close = useElDialog(
{
modelValue: true,
},
{
default: () => h(model),
footer: () => 'footer slot',
header: () => 'header slot',
}
)
resolveComponent
对于全局引入的组件 vue 提供了 resolveComponent 方法.
const { h, resolveComponent } = Vue
export default {
setup() {
const ButtonCounter = resolveComponent('ButtonCounter')
return () => {
return h(ButtonCounter)
}
},
}
const { h, resolveComponent } = Vue
export default {
render() {
const ButtonCounter = resolveComponent('ButtonCounter')
return h(ButtonCounter)
},
}