如何在TS文件中使用@vue/composition-api创建新组件实例?
原因说明
@vue/composition-api 的 defineComponent 仅做组件配置的类型推导,返回值是普通组件选项对象,不是类组件模式下继承自Vue的构造函数,因此无法直接通过new关键字调用生成实例。
实现方法
方案1:保留原有new调用习惯,通过Vue.extend转构造函数
和原有类组件的调用逻辑最接近,先把defineComponent返回的组件配置传入Vue.extend生成可实例化的构造函数,再new创建实例即可:
// SomeComponent.vue import { defineComponent, ref } from '@vue/composition-api'; export default defineComponent({ props: { title: String }, setup() { const count = ref(0); const add = () => count.value++; return { count, add } } });
// 任意.ts文件 import Vue from 'vue'; import SomeComponent from './SomeComponent.vue'; // 生成组件构造函数 const ComponentCtor = Vue.extend(SomeComponent); // 实例化,可传入props、事件监听等配置 const component = new ComponentCtor({ propsData: { title: '测试组件' } }); // 需要挂载到DOM时调用$mount // component.$mount('#mount-node');
这种方式创建的实例和类组件模式下new生成的实例完全一致,组件生命周期、响应式状态、实例方法都可正常使用,TS类型会自动推导,不需要额外写类型声明。
方案2:动态渲染场景用render函数创建实例
如果只是需要动态渲染组件、不需要脱离Vue上下文手动管理实例,直接用render函数生成挂载即可,不需要手动调用new创建目标组件:
import Vue from 'vue'; import SomeComponent from './SomeComponent.vue'; // 创建挂载根实例 const vm = new Vue({ render(h) { return h(SomeComponent, { props: { title: '动态渲染组件' }, on: { confirm: () => console.log('组件触发confirm事件') } }) } }).$mount(); // 目标组件实例可通过$children获取 const component = vm.$children[0]; // 不需要时销毁根实例即可,目标组件会同步走销毁流程 // vm.$destroy();
注意点
- 手动创建并挂载的组件实例,不用时必须手动调用
$destroy()销毁,避免内存泄漏 - 非特殊场景不推荐手动创建组件实例,优先使用框架内置的动态组件
<component :is="">实现动态渲染,更符合Vue的设计逻辑,也能避免手动管理实例带来的内存、生命周期异常问题。
内容的提问来源于stack exchange,提问作者Valerii Strilets
相关产品推荐
相关产品推荐

