Angular5中点击触发懒加载模块且不修改URL与路由可行吗?
在Angular 5中实现点击触发模块懒加载(不修改URL/路由配置)
嘿,这个需求完全可以实现!不用碰路由配置,也不会改动URL,纯靠组件级的动态加载就能搞定。下面给你一步步拆解实现思路和代码示例:
核心思路
我们要利用Angular 5支持的ES6动态import()语法来懒加载模块文件,再通过ComponentFactoryResolver把模块里的组件动态渲染到页面指定容器中——全程和路由系统无关,自然不会影响URL。
具体实现步骤
1. 准备懒加载模块
先创建一个普通的Angular模块(比如LazyModule),把需要懒加载的组件(比如LazyComponent)声明进去,并且一定要把组件加入entryComponents数组(因为是动态渲染,Angular需要提前知道这个组件的存在):
// lazy.module.ts import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { LazyComponent } from './lazy.component'; @NgModule({ declarations: [LazyComponent], imports: [CommonModule], entryComponents: [LazyComponent] // 关键:动态加载的组件必须在这里声明 }) export class LazyModule { }
2. 在父组件中实现点击加载逻辑
在需要触发懒加载的父组件里,我们需要:
- 通过
@ViewChild获取用来渲染懒加载组件的容器 - 注入
ComponentFactoryResolver和Compiler(用来编译动态加载的模块) - 编写点击事件方法,完成模块懒加载和组件渲染
// parent.component.ts import { Component, ViewChild, ViewContainerRef, ComponentFactoryResolver, Compiler, Injector } from '@angular/core'; @Component({ template: ` <button (click)="loadLazyModule()">点击加载懒加载模块</button> <!-- 用来渲染懒加载组件的容器 --> <div #lazyContainer></div> ` }) export class ParentComponent { @ViewChild('lazyContainer', { read: ViewContainerRef }) lazyContainer: ViewContainerRef; constructor( private cfr: ComponentFactoryResolver, private compiler: Compiler, private injector: Injector ) { } loadLazyModule() { // 动态加载懒加载模块文件,Webpack会自动把这个模块打包成单独的chunk import('./lazy/lazy.module').then(module => { const LazyModule = module.LazyModule; // 编译模块并创建模块引用 const moduleFactory = this.compiler.compileModuleSync(LazyModule); const moduleRef = moduleFactory.create(this.injector); // 获取懒加载组件的工厂 const componentFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(module.LazyComponent); // 清空容器(可选),然后渲染组件 this.lazyContainer.clear(); const componentRef = this.lazyContainer.createComponent(componentFactory); // 如果需要给懒加载组件传值,直接操作instance即可 // componentRef.instance.someInput = '来自父组件的参数'; }); } }
3. 配置注意事项
- 如果你的项目用了AOT编译,需要确保
tsconfig.json中module设置为esnext,这样才能支持动态import()语法 - 确保父组件所在的模块已经导入了
CommonModule(如果需要用到Angular内置指令的话)
为什么这种方法可行?
这种方式完全绕开了Angular的路由系统,直接通过动态加载模块文件+动态渲染组件实现懒加载,所以:
- 不会修改浏览器URL
- 不需要修改任何现有路由配置
- Webpack会自动把懒加载模块拆分成单独的chunk文件,只有点击时才会请求加载
内容的提问来源于stack exchange,提问作者Parth Godhani
相关产品推荐
相关产品推荐

