Angular 5:点击触发组件加载至div的实现方案问询
嘿,这个需求我之前做后台管理系统的时候刚好遇到过!完全不用路由,也不用提前把所有表单都藏在页面里占资源,用动态组件加载+指定DOM挂载就能完美解决,给你分Vue和React两种常用框架的具体实现方式:
Vue 实现方案
先搭好基础结构,子导航和表单挂载的目标容器:
<template> <div class="form-page"> <!-- 子导航栏 --> <div class="sub-nav"> <button v-for="formItem in formList" :key="formItem.id" @click="loadTargetForm(formItem.componentPath)" class="nav-btn" > {{ formItem.name }} </button> </div> <!-- 表单挂载的目标容器 --> <div ref="formContainer" class="form-container"></div> </div> </template>
然后实现核心的动态加载和挂载逻辑:
<script setup> import { ref, h, render } from 'vue' const formContainer = ref(null) // 存储当前已挂载的组件实例,切换时销毁旧组件避免内存泄漏 let currentFormInstance = null // 子导航对应的表单列表,把每个表单的路径和名称配置好 const formList = [ { id: 1, name: '用户信息表单', componentPath: './forms/UserInfoForm.vue' }, { id: 2, name: '订单提交表单', componentPath: './forms/OrderSubmitForm.vue' }, // ... 剩下10个表单按这个格式补充 ] const loadTargetForm = async (componentPath) => { // 先销毁之前的表单组件 if (currentFormInstance) { render(null, formContainer.value) currentFormInstance = null } try { // 动态导入目标表单组件——只有点击时才会加载对应组件的资源 const { default: TargetForm } = await import(componentPath) // 创建组件虚拟节点并挂载到指定div const formVnode = h(TargetForm) currentFormInstance = render(formVnode, formContainer.value) } catch (error) { console.error('表单加载失败:', error) // 这里可以给用户提示,比如弹出错误弹窗 } } </script>
React 实现方案
同样先写页面结构:
import { useRef } from 'react' import { createRoot } from 'react-dom/client' function FormNavigationPage() { const formContainer = useRef(null) // 存储上一个表单的卸载函数,切换时清理旧组件 let unmountPreviousForm = null // 表单导航配置列表 const formList = [ { id: 1, name: '用户信息表单', componentPath: './forms/UserInfoForm' }, { id: 2, name: '订单提交表单', componentPath: './forms/OrderSubmitForm' }, // ... 补充剩余表单 ] const loadTargetForm = async (componentPath) => { // 卸载之前的表单组件 if (unmountPreviousForm) { unmountPreviousForm() } try { // 动态导入目标表单组件 const { default: TargetForm } = await import(componentPath) // 挂载到指定的div容器中 const root = createRoot(formContainer.current) root.render(<TargetForm />) // 保存卸载函数,供下次切换时使用 unmountPreviousForm = () => root.unmount() } catch (error) { console.error('表单加载失败:', error) // 可添加用户友好的错误提示 } } return ( <div className="form-page"> <div className="sub-nav"> {formList.map(formItem => ( <button key={formItem.id} onClick={() => loadTargetForm(formItem.componentPath)} className="nav-btn" > {formItem.name} </button> ))} </div> <div ref={formContainer} className="form-container"></div> </div> ) } export default FormNavigationPage
额外优化建议
- 组件缓存:如果不想让用户切换回已打开过的表单时重新加载,可以加一个缓存对象,把已加载的组件存起来,下次直接复用,比如Vue里可以用
const componentCache = ref({}),导入前先检查缓存里有没有。 - 样式隔离:如果表单之间有样式冲突,可以用CSS Modules或者Shadow DOM来做样式隔离,避免互相影响。
- 加载状态:在动态导入的过程中,可以给容器加个加载动画,提升用户体验。
内容的提问来源于stack exchange,提问作者j-p
相关产品推荐
相关产品推荐

