You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue 3 如何实现编程式动态创建并挂载子组件?

Vue3 编程式动态创建挂载组件实现方案

Vue3移除了Vue2中的Vue.extendAPI,你可以通过以下两种方式实现同等功能:


方式一:createVNode + render(推荐,继承当前组件上下文)

该方案可以直接继承当前父组件的应用上下文,不需要手动注册store、i18n等插件,和你Vue2中的原有行为完全一致。

选项式API实现:

import { createVNode, render } from 'vue'
import ChildComponent from './ChildComponent.vue'

// ParentComponent.vue
export default {
  methods: {
    createChild() {
      // 1. 创建子组件虚拟节点,传递props和事件
      const childVNode = createVNode(ChildComponent, {
        // 直接写props参数,不需要用propsData字段
        propA: '测试参数',
        propB: 123,
        // 自定义事件用on+驼峰命名绑定,比如@close对应onClose
        onClose: () => {
          // 组件销毁逻辑
          render(null, container)
          document.body.removeChild(container)
        }
      })
      // 2. 继承当前组件的应用上下文,$store、$i18n等插件能力自动生效
      childVNode.appContext = this.$.appContext
      // 3. 创建挂载容器
      const container = document.createElement('div')
      document.body.appendChild(container)
      // 4. 渲染挂载组件
      render(childVNode, container)

      // 如需获取组件实例,可通过以下方式访问
      const childInstance = childVNode.component.proxy
    }
  }
}

组合式API实现:

import { getCurrentInstance, createVNode, render } from 'vue'
import ChildComponent from './ChildComponent.vue'

export default {
  setup() {
    const instance = getCurrentInstance()

    const createChild = () => {
      const childVNode = createVNode(ChildComponent, {
        propA: '测试参数',
        onClose: () => {
          render(null, container)
          document.body.removeChild(container)
        }
      })
      childVNode.appContext = instance.appContext
      const container = document.createElement('div')
      document.body.appendChild(container)
      render(childVNode, container)
    }

    return { createChild }
  }
}

方式二:createApp实现(独立上下文场景)

如果需要创建完全独立、不共享父组件上下文的组件实例,可以用该方案:

import { createApp } from 'vue'
import ChildComponent from './ChildComponent.vue'
import store from '@/store'
import i18n from '@/i18n'

export default {
  methods: {
    createChild() {
      const container = document.createElement('div')
      document.body.appendChild(container)
      // 创建独立app实例,手动注册需要的插件
      const childApp = createApp(ChildComponent, {
        propA: '测试参数',
        onClose: () => {
          childApp.unmount()
          document.body.removeChild(container)
        }
      })
      // 手动挂载需要的插件
      childApp.use(store).use(i18n)
      // 挂载组件
      childApp.mount(container)
    }
  }
}

注意事项

  • 组件使用完成后务必执行销毁逻辑,避免内存泄漏
  • 如需传递插槽,可以在createVNode第三个参数传入插槽配置,示例:
const childVNode = createVNode(ChildComponent, { propA: 'xxx' }, {
  default: () => '默认插槽内容',
  header: () => h('div', '自定义头部')
})
  • 自定义事件绑定严格遵循on+驼峰命名规则,比如事件名update:modelValue对应onUpdate:modelValue

内容的提问来源于stack exchange,提问作者srjjio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 19:30:03