聊聊Angular中懒加载模块并动态显示它的组件

不通过路由的情况下, 怎么懒加载一个angular模块,并动态创建其中声明的组件?下面本篇文章给大家介绍一下方法,希望对大家有所帮助!

聊聊Angular中懒加载模块并动态显示它的组件

环境: Angular 13.x.x

angular中支持可以通过路由来懒加载某些页面模块已达到减少首屏尺寸, 提高首屏加载速度的目的. 但是这种通过路由的方式有时候是无法满足需求的。【相关教程推荐:《angularjs视频教程》】

比如, 点击一个按钮后显示一行工具栏, 这个工具栏组件我不希望它默认打包进main.js, 而是用户点按钮后动态把组件加载并显示出来.

那为什么要动态加载呢? 如果直接在目标页面组件引入工具栏组件, 那么工具栏组件中的代码就会被打包进目标页面组件所在的模块, 这会导致目标页面组件所在的模块生成的js体积变大; 通过动态懒加载的方式, 可以让工具栏组件只在用户点了按钮后再加载, 这样就可以达到减少首屏尺寸的目的.

为了演示, 新建一个angular项目, 然后再新建一个ToolbarModule, 项目的目录结构如图

img

为了达到演示的目的, 我在ToolbarModule的html模板中放了个将近1m的base64图片, 然后直接在AppModule中引用ToolbarModule, 然后执行ng build, 执行结果如图

img

可以看到打包尺寸到达了1.42mb, 也就是说用户每次刷新这个页面, 不管用户有没有点击显示工具栏按钮, 工具栏组件相关的内容都会被加载出来, 这造成了资源的浪费, 所以下面将ToolbarModule从AppModule的imports声明中移除, 然后在用户点击首次点击显示时懒加载工具栏组件.

懒加载工具栏组件

首先, 新建一个ToolbarModule和ToolbarComponent, 并在ToolbarModule声明ToolbarComponent

img

toolbar.module.ts
import { NgModule } from '@angular/core';import { CommonModule } from '@angular/common';import { ToolbarComponent } from './toolbar.component'; @NgModule({    declarations: [ToolbarComponent],    imports: [CommonModule],    exports: [ToolbarComponent],})class ToolbarModule {} export { ToolbarComponent, ToolbarModule };

登录后复制

toolbar.component.ts
import { Component, OnInit } from '@angular/core';@Component({    selector: 'toolbar',    templateUrl: './toolbar.component.html',    styles: [        `    svg {      width: 64px;      height: 64px;    }    img {      width: 64px;      height: 64px;      object-fit: cover;    }    `,    ],})export class ToolbarComponent implements OnInit {    constructor() {}    ngOnInit(): void {}}

登录后复制

toolbar.component.html

<img src="https://www.php.cn/faq/" alt="">

登录后复制

然后再AppComponent的中按钮点击事件处理程序中写加载工具栏模块的代码:

app.component.ts
import { Component, createNgModuleRef, Injector, ViewChild, ViewContainerRef } from '@angular/core';@Component({    selector: 'root',    template: `               

                 

                                    

                 

                                      

首屏内容

                                             `,})export class AppComponent {    title = 'ngx-lazy-load-demo';    toolbarLoaded = false;    isToolbarVisible = false;    @ViewChild('toolbar', { read: ViewContainerRef }) toolbarViewRef!: ViewContainerRef;    constructor(private _injector: Injector) {}    toggleToolbarVisibility() {        this.isToolbarVisible = !this.isToolbarVisible;        this.loadToolbarModule().then();    }    private async loadToolbarModule() {        if (this.toolbarLoaded) return;        this.toolbarLoaded = true;        const { ToolbarModule, ToolbarComponent } = await import('./toolbar/toolbar.module');        const moduleRef = createNgModuleRef(ToolbarModule, this._injector);        const { injector } = moduleRef;        const componentRef = this.toolbarViewRef.createComponent(ToolbarComponent, {            injector,            ngModuleRef: moduleRef,        });    }}

登录后复制

关键在于其中的第32-42行, 首先通过一个动态import导入toolbar.module.ts中的模块, 然后调用createNgModuleRef并传入当前组件的Injector作为ToolbarModule的父级Injector, 这样就实例化了ToolbarModule得到了moduleRef对象, 最后就是调用html模板中声明的的ViewContainerRef对象的createComponent方法创建ToolbarComponent组件

private async loadToolbarModule() {    if (this.toolbarLoaded) return;    this.toolbarLoaded = true;    const { ToolbarModule, ToolbarComponent } = await import('./toolbar/toolbar.module');    const moduleRef = createNgModuleRef(ToolbarModule, this._injector);    const { injector } = moduleRef;    const componentRef = this.toolbarViewRef.createComponent(ToolbarComponent, {        injector,        ngModuleRef: moduleRef,    });}

登录后复制

此时再来看下这番操作后执行ng build打包的尺寸大小

img

可以看到首屏尺寸没有开头那么离谱了, 原因是没有在AppModule和AppComponent直接导入ToolbarModule和ToolbarComponent, ToolbarModule被打进了另外的js文件中(Lazy Chunk Files), 当首次点击显示按钮时, 就会加载这个包含ToolbarModule的js文件

注意看下面的gif演示中, 首次点击显示按钮, 浏览器网络调试工具中会多出一个对src_app_toolbar_toolbar_module_ts.js文件的请求

img

更多编程相关知识,请访问:编程视频!!

以上就是聊聊Angular中懒加载模块并动态显示它的组件的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2698063.html

(0)
上一篇 2025年3月7日 18:46:48
下一篇 2025年2月24日 14:07:40

AD推荐 黄金广告位招租... 更多推荐

相关推荐

发表回复

登录后才能评论