详解使用路由延迟加载 Angular 模块


Posted in Javascript onOctober 12, 2017

Angular 非常模块化,模块化的一个非常有用的特性就是模块作为延迟加载点。延迟加载意味着可以在后台加载一个模块和其包含的所有组件等资源。这样 Angular 就不需要在第一个界面从服务器下载所有的文件,直到您请求它,才下载相应的模块。这对提供性能和减少首屏的初始下载文件尺寸有巨大的帮助。而且它可以很容易设置。

这里将使用一个简单示例来演示这个特性是如何工作的。将应用拆分为多个不同的模块,可以在需要的时候再进行延迟加载。

延迟加载的路由需要在根模块之外定义,所以,你需要将需要延迟加载的功能包含在功能模块中。

我们使用 Angular CLI 来创建一个演示项目:Demo.

ng new demo

然后,进入到 demo 文件夹中。安装必要的 package。

npm i

在安装之后,我们创建一个新的模块 shop。在 angular CLI 中,ng 是命令提示指令,g 表示 generate,用来创建某类新 item。

创建新的名为 shop 的模块就是:

ng g module shop

这会导致在 Angular 项目的 src/app 文件下创建一个新的文件夹,并添加一个名为 shop.module.ts 的模块定义文件。

然后,我们在默认的 app 模块和新创建的 shop 模块中分别创建组件。

ng g c home/home
ng g c shop/cart
ng g c shop/checkout 
ng g c shop/confirm

CLI 会将 home 分配到 app 模块中,将 cart、checkout、confirm 分配到 shop 模块中,比如,

此时的 shop.module.ts 内容如下:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { CheckoutComponent } from './checkout/checkout.component';
import { CartComponent } from './cart/cart.component';
import { ConfirmComponent } from './confirm/confirm.component';

@NgModule({
 imports: [
  CommonModule
 ],
 declarations: [CheckoutComponent, CartComponent, ConfirmComponent]
})
export class ShopModule { }

修改根组件

Angular CLI 默认生成的 app.component.ts 组件是应用的主页面,其中包含了一些关于 Angular 的介绍信息,我们将它修改成我们需要的内容。将默认生成的 app.component.html 内容修改为如下内容。

<!--The content below is only a placeholder and can be replaced.-->
<h1>Lazy Load Module</h1>
<a [routerLink]="['/shop']" >Shop Cart</a>
<router-outlet>
</router-outlet>

这里提供了一个占位的 router-outlet,各个组件将显示在这里面。

同时,提供了一个导航链接,可以直接导航到 /shop/cart 组件。

创建路由

根路由

首先创建根路由。

我们在 app 文件夹中,添加一个名为 main.routing.ts 的路由配置文件。内容如下:

import { Routes } from '@angular/router';
// HomeComponent this components will be eager loaded
import { HomeComponent } from './home/home.component';

export const routes: Routes = [
  { path: '', component: HomeComponent, pathMatch: 'full' },
  { path: 'shop', loadChildren: './shop/shop.module#ShopModule' },
  { path: '**', component: HomeComponent }
];

其中,home 组件是正常的提前加载。

需要注意的是一下几点:

1. 我们使用了 loadChildren 来延迟加载一个模块。而不是使用提前加载所使用的 component。
2. 我们使用了一个字符串而不是符号来避免提前加载。
3. 我们不仅定义了模块的路径,还提供了模块的类名。

在 app.module.ts 中启用根路由。主要需要使用 forRoot 来启用根路由。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { routes } from './main.routing';
import { RouterModule } from '@angular/router';

@NgModule({
 declarations: [
  AppComponent,
  HomeComponent
 ],
 imports: [
  BrowserModule,
  RouterModule.forRoot(routes)
 ],
 providers: [],
 bootstrap: [AppComponent]
})
export class AppModule { }

模块路由

定义模块路由

对于 shop 模块来说,定义路由就没有什么特别了,我们这里可以定义一个名为 shop.route.ts 的路由定义文件,内容如下所示:

import { Routes } from '@angular/router'; 
import { CartComponent } from './cart/cart.component'; 
import { CheckoutComponent } from './checkout/checkout.component'; 
import { ConfirmComponent } from './confirm/confirm.component'; 
export const routes: Routes = [   
     { path: '', component: CartComponent },   
     { path: 'checkout', component: CheckoutComponent },  
     { path: 'confirm', component: ConfirmComponent } 
];

还需要修改一下模块定义文件 shop.module.ts 文件,以使用这个路由定义。注意我们需要使用 forChild 来启用子路由。

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { CheckoutComponent } from './checkout/checkout.component';
import { CartComponent } from './cart/cart.component';
import { ConfirmComponent } from './confirm/confirm.component';

import { routes } from './shop.routing'; 
import { RouterModule } from '@angular/router';

@NgModule({
 imports: [
  CommonModule,
  RouterModule.forChild(routes)
 ],
 declarations: [CheckoutComponent, CartComponent, ConfirmComponent]
})
export class ShopModule { }

已经一切就绪了。

测试延迟加载

现在启动应用。

ng serve

默认会在 4200 端口启动应用,请打开浏览器,访问:http://localhost:4200/

访问首页的网络访问如下,其中并不包含功能模块的内容。

详解使用路由延迟加载 Angular 模块

我们先将网络请求的历史记录清除掉。

然后点击链接,访问 /shop/cart 的时候,网络请求如下,可以看到一个新的脚本文件被加载,这里包含的就是延迟加载的功能模块。

详解使用路由延迟加载 Angular 模块

仅仅功能模块被加载了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript中void(0)的具体含义解释
Feb 27 Javascript
js 实现打印网页中定义的部分内容的代码
Apr 01 Javascript
js实现图片轮换效果代码
Apr 16 Javascript
使用jquery选择器如何获取父级元素、同级元素、子元素
May 14 Javascript
javascript产生随机数方法汇总
Jan 25 Javascript
jQuery实现的文字hover颜色渐变效果实例
Feb 20 Javascript
jQuery简单实现iframe的高度根据页面内容自适应的方法
Aug 01 Javascript
Bootstrap源码解读网格系统(3)
Dec 22 Javascript
bootstrap时间控件daterangepicker使用方法及各种小bug修复
Oct 25 Javascript
vue.js 实现评价五角星组件的实例代码
Aug 13 Javascript
基于iview-admin实现动态路由的示例代码
Oct 02 Javascript
Vue 解决路由过渡动画抖动问题(实例详解)
Jan 05 Javascript
ionic3+Angular4实现接口请求及本地json文件读取示例
Oct 11 #Javascript
js实现单张图片平移切换效果
Oct 11 #Javascript
jQuery自动或手动图片切换效果
Oct 11 #jQuery
简单实现vue验证码60秒倒计时功能
Oct 11 #Javascript
mui框架移动开发初体验详解
Oct 11 #Javascript
Scala解析Json字符串的实例详解
Oct 11 #Javascript
jQuery使用bind函数实现绑定多个事件的方法
Oct 11 #jQuery
You might like
雄兵连三大错觉:凯莎没了,凉冰阵亡了,华烨觉得自己又行了
2020/04/09 国漫
第一个无线电台是由谁发明的
2021/03/01 无线电
解决phpmyadmin 乱码,支持gb2312和utf-8
2006/11/20 PHP
php 连接mysql连接被重置的解决方法
2011/02/15 PHP
php调用dll的实例操作动画与代码分享
2012/08/14 PHP
PHP中extract()函数的定义和用法
2012/08/17 PHP
memcache一致性hash的php实现方法
2015/03/05 PHP
jquery制作 随机弹跳的小球特效
2015/02/01 Javascript
JS实现具备延时功能的滑动门菜单效果
2015/09/17 Javascript
jquery根据td给相同tr下其他td赋值的实现方法
2016/10/05 Javascript
微信小程序 触控事件详细介绍
2016/10/17 Javascript
微信小程序 删除项目工程实现步骤
2016/11/10 Javascript
Ionic+AngularJS实现登录和注册带验证功能
2017/02/09 Javascript
JS中SetTimeout和SetInterval使用初探
2017/03/23 Javascript
JavaScript中EventLoop介绍
2018/01/22 Javascript
Canvas实现微信红包照片效果
2018/08/21 Javascript
详解React项目如何修改打包地址(编译输出文件地址)
2019/03/21 Javascript
ES6中Promise的使用方法实例总结
2020/02/18 Javascript
vue自定义树状结构图的实现方法
2020/10/18 Javascript
Javascript数组及类数组相关原理详解
2020/10/29 Javascript
[01:57]DOTA2上海特锦赛小组赛解说单车采访花絮
2016/02/27 DOTA
[53:36]Liquid vs VP Supermajor决赛 BO 第三场 6.10
2018/07/05 DOTA
详解Python的数据库操作(pymysql)
2019/04/04 Python
Django2 连接MySQL及model测试实例分析
2019/12/10 Python
python pip安装包出现:Failed building wheel for xxx错误的解决
2019/12/25 Python
Tensorflow 实现将图像与标签数据转化为tfRecord文件
2020/02/17 Python
Python super()方法原理详解
2020/03/31 Python
使用Keras构造简单的CNN网络实例
2020/06/29 Python
HTML5几个设计和修改的页面范例分享
2015/09/29 HTML / CSS
La Senza官网:北美顶尖性感内衣品牌
2018/08/03 全球购物
Zatchels官网:英国剑桥包品牌
2021/01/12 全球购物
婚纱摄影师求职信
2014/03/07 职场文书
助学贷款贫困证明
2014/09/23 职场文书
个人收入证明范本
2015/06/12 职场文书
教师研修随笔感言
2015/11/18 职场文书
CentOS7安装GlusterFS集群以及相关配置
2022/04/12 Servers