2024-02-01 04:42:48
在 Vue3 中,createApp 方法本身设计上通常差码明只调用一次以创建根应用实例,但通过合理组织代码和利用 Vue3 的特性,可以变相实现类似“多次调用 createApp”的效果,主要适用于手动挂载组件或渲染函数的场景。以下是具体实现方式及关键注意事项:
一、核心实现思路Vue3 中每次调用 createApp 都会生成一个独立的应用实例,但需注意:
创建独立应用实例每次需要显示弹窗时,动态创建新的应用实例并挂载到隐藏的 DOM 容器中:
import { createApp } from 'vue';import ModalComponent from './ModalComponent.vue';function showModal(propsData) { // 创建临时容器 const container = document.createElement('div'); document.body.appendChild(container); // 创建独立应用实例 const app = createApp(ModalComponent, { ...propsData }); app.mount(container); // 返回卸载函数 return () => { app.unmount(); document.body.removeChild(container); };}// 使用示例const closeModal = showModal({ title: '提示', content: '操作成功' });// 调用 closeModal() 关闭弹窗关键点
每次调用 showModal 都会生成新的应用实例,避免状态污染。
通过返回卸载函数,实现灵活控制生命周期。
手动挂载渲染函数若需获取组件渲虚告染后的文本内容(如导出 CSV),可手动挂载组件并提取 textContent:
import { createApp, h } from 'vue';function renderToText(Component, props) { const container = document.createElement('div'); document.body.appendChild(container); const app = createApp({ render: () => h(Component, props), }); app.mount(container); // 获取渲染后的文本 const textContent = container.textContent; // 卸载并清理 app.unmount(); document.body.removeChild(container); return textContent;}// 使用示例const text = renderToText(MyComponent, { data: [1, 2, 3] });console.log(text); // 输出渲染后的文本注意事项
无卸载方法的风险:若错误使用 createApp(App).mount(el),会导致无法卸载。必须按正确调用链操作。
性能优化:频繁挂载/卸载时,可复用 DOM 容器或使用 Teleport 优化性能。
封装挂载逻辑将应用创建、挂载、卸载封装为通用函数:
function createMountableApp(Component, props = {}) { const container = document.createElement('div'); document.body.appendChild(container); const app = createApp(Component, props); app.mount(container); return { element: container, unmount: () => { app.unmount(); document.body.removeChild(container); }, };}// 使用示例const { unmount } = createMountableApp(MyComponent);// 调用 unmount() 卸载与 Vue2 的区别
Vue2 中通过 Vue.extend 创建子类,可多次实例化;Vue3 中改用 createApp,需通过上述模式模拟类似行为。
Vue3 的组合式 API 更适合这种灵活的手动挂载需求。
动态弹窗、通知等独立组件。
服务器端渲染(SSR)或静态内容生成。
需要获取组件渲染结果的工具函数。
错误调用导致无法卸载,引发内存泄漏。
频繁操作 DOM 影响性能,需合理复用容器。
通过以上方法,可以在 Vue3 中安全地实现类似“多次调用 createApp”的效果,同时保持代码的清晰性和可维护性。