Vue 3组合式函数动态挂载组件需用createVNode+render手动创建并渲染虚拟节点到DOM容器,再插入页面,同时提供卸载方法;事件需通过props传入,不继承父上下文。

在 Vue 3 的组合式函数(Composable)中动态挂载组件,核心是利用 createApp + createVNode + render 三者协作,而非依赖模板中的 。这种方式适合弹窗、提示框、临时浮层等“非声明式、运行时创建”的场景。
关键步骤:手动创建并挂载到真实 DOM
组合式函数中不直接操作 app.mount()(那是根实例用的),而是通过虚拟节点渲染到一个新创建或指定的 DOM 容器:
- 用
createVNode将组件构造器转为虚拟节点(支持 props、事件、插槽) - 用
render把该 vnode 渲染进一个真实 DOM 元素(如document.createElement('div')) - 将该 DOM 元素插入页面(如
document.body.appendChild(el)) - 返回卸载方法:调用
render(null, el)清空,并移除 DOM 节点
典型实现:封装一个可复用的挂载函数
以下是一个标准的组合式函数示例(TypeScript 友好):
import { createVNode, render, getCurrentInstance } from 'vue'
import type { Component, VNode, App } from 'vue'
export function useMountComponent<t extends component>(
component: T,
props?: Record<string any>,
children?: any
) {
const container = document.createElement('div')
let vnode: VNode | null = null
const mount = () => {
vnode = createVNode(component, props, children)
render(vnode, container)
document.body.appendChild(container)
}
const unmount = () => {
if (vnode && container.parentNode) {
render(null, container)
container.remove()
vnode = null
}
}
return { mount, unmount }
}
</string></t>使用时只需传入组件、配置项即可:
从零开始编排 SpringBoot+Vue 全栈项目工作流,适用于新建全栈项目或完整脚手架请求,触发后依次调用 product‑spec‑builder(需求调研)等模块。
// 在 setup 或 composable 中
const { mount, unmount } = useMountComponent(ConfirmModal, {
title: '确认删除?',
onConfirm: () => console.log('已确认'),
onClose: unmount
})
mount()
注意事项:事件与响应式需显式桥接
动态挂载的组件无法自动继承父组件上下文(如 getCurrentInstance() 为 null),所以:
- 事件回调必须由外部传入 props(如
onConfirm),不能依赖emit后再由父级监听 - 若需访问全局属性(如
$message),需提前通过app.config.globalProperties注册,并在挂载前手动注入上下文(较复杂,一般推荐传函数) - 避免多次重复挂载同一组件实例;每次调用应新建 vnode 和容器
替代方案:配合 defineAsyncComponent 懒加载
如果目标是“按需加载+动态切换”,而非“完全运行时创建”,更轻量的做法是结合 defineAsyncComponent 和 :
- 用
defineAsyncComponent(() => import('./Modal.vue'))包裹异步组件 - 在模板中用
- 在组合式函数中控制
modalComp的赋值与清空(即“逻辑挂载”,非真实 DOM 挂载)
这种方式无需手动管理 DOM,也天然支持 和响应式更新,适合 tab 切换、路由级动态组件等场景。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










