前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版

Angular7 入门总结 从环境搭建到路由的完整笔记

首页2019-01-09 16:55:24Front-End
JavaScriptAngularTypeScript

起因是我要做一个 Ionic 4 的混合应用。Ionic 那几个大版本一直绑着 Angular,模板语法、依赖注入、模块声明全是 Angular 那一套,不把 Angular 和 TypeScript 的基础补上,连一个页面跳转都写不明白。我之前整理过一篇 Ionic 3 的踩坑总结,当时是硬着头皮往前推的,这次干脆停下来,把 Angular 7 从头过一遍,边写 demo 边记,攒成了这篇笔记。

所以这篇不打算论证「Angular 有多好」。它更像是一个从 jQuery、Vue 那边过来的人,把 Angular 的心智模型对齐到能上手写业务的程度。读完你应该能独立搭起项目、写组件、拆服务、配路由,也能看懂别人的 Angular 代码在干什么。

在本篇文章中,我们将从浅入深,和大家一起学习以下知识:

  • Angular 的定位,以及它和 Vue、React 在工程取向上的差别
  • 用 Angular CLI 搭环境、建项目,生成的目录里哪几个文件才是重点
  • 组件、模板语法、内置指令、管道,配三个能跑起来的完整小案例
  • 服务与依赖注入,怎么把状态从组件里挪出去
  • 八个生命周期钩子的触发顺序,以及每一个该干什么
  • RxJS 的 Observable 和 Promise 到底差在哪,RxJS 6 又改了什么
  • 用 HttpClient 发 get、post、jsonp 请求
  • 路由配置、路由传参、js 跳转和父子路由

# 一、Angular 介绍

Angular 是谷歌开源的 web 前端框架,前身 AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后来被 Google 接手维护,Google 自家不少产品都在用它。

它和 Vue、React 最大的差别不在语法,而在「给不给你选择」这件事上。Vue 和 React 都是库或者说轻框架,路由、状态、HTTP 请求你自己配;Angular 是把路由、依赖注入、HTTP 客户端、表单、测试脚手架一整套全给你,代价是你得接受它的写法。这套取向在中大型企业级项目里很省心,几十个人的团队目录结构和分层方式天然一致;放到三五个页面的小项目上,就显得笨重。

  • 从 2019 年初的项目数统计看,angular(1.x、2.x、4.x、5.x、6.x、7.x) 加起来的存量非常大,尤其是企业内部系统
  • Angular 从 2.x 开始就以 TypeScript 为一等公民,类型、装饰器、接口这些都是日常写法,不是可选项

写这篇的时候是 2018 年 11 月发布的 angular7.x。官方走的是固定节奏的大版本发布,每隔几个月就会有一个新的主版本号,所以这份笔记里的基础概念同样适用于后面的 Angular8.x、Angular9.x。

Angular 官方文档首页与版本说明

这里得先说一句时效性。这篇写于 Angular 7 时代,之后 Angular 的大版本已经走出去很远了。Ivy 渲染器、standalone components(不用再写 NgModule 的独立组件)、signals 这套细粒度响应式,还有 @if / @for 这类新的模板控制流语法,都是这篇之后才有的东西。本文的写法在当年的项目里是标准写法,现在读到的老代码大量还是这个样子,所以留着不动是有价值的;但如果你是新起项目,具体用哪套 API 请以官方文档当前版本为准,我不确定各个特性具体落在哪个版本号上,就不在这里乱猜了。后面每一章我都会在末尾单独起一小段,说清楚这块后来往哪个方向演进了。

学习 Angular 必备基础

想顺畅读下去,html、css、js、es6 这几样是底子,另外 TypeScript 得会一点。倒不用把泛型、条件类型这些啃透,能看懂类型注解、interface、class 和装饰器语法就够开工了,剩下的边写边补。

# 二、Angular 环境搭建及创建项目

# 2.1 环境搭建

Angular 的工程化程度高,好处是脚手架帮你把编译、开发服务器、测试、打包全配好了,坏处是环境这一步没弄对,后面全是莫名其妙的报错。所以这一节值得慢一点。

1. 安装 nodejs

装 angular 的机器上必须有 nodejs,选 LTS 稳定版,别去追奇数版本号的当前版。Angular CLI 每个大版本都有自己支持的 Node 版本区间,装之前先去官方的版本兼容表对一眼,能省掉一大半「安装成功但 ng serve 起不来」的问题。

2. 安装 cnpm

当年国内直连 npm 官方源经常超时,@angular/cli 这个包依赖又特别多,所以一般先用 npm 装一个走淘宝镜像的 cnpm。

npm install -g cnpm --registry=https://registry.npm.taobao.org
@前端进阶之旅: 代码已经复制到剪贴板

这里有个坑要注意,淘宝源后来做过域名迁移,registry.npm.taobao.org 这个地址已经不是主推的了,现在的地址是 registry.npmmirror.com。你要是照上面这行敲报证书错误,八成就是撞上这个了,换成新域名即可。另外现在 npm 本身速度也还行,直接 npm config set registry 换源比再装一层 cnpm 更干净,cnpm 扁平化 node_modules 的方式偶尔会和某些包的路径假设打架。

3. 使用 npm/cnpm 命令安装 angular/cli

@angular/cli 是全局命令行工具,装完你就有了 ng 这个命令,后面建项目、生成组件、起开发服务器全靠它。

npm install -g @angular/cli 

# 或者 
cnpm install -g @angular/cli
@前端进阶之旅: 代码已经复制到剪贴板

装完敲 ng v,它会打印 CLI 版本、Angular 各个包的版本、Node 版本和操作系统。这一步不只是确认装没装上,更重要的是核对 CLI 版本和你要建的项目版本是不是一套。

执行 ng v 输出的 Angular CLI 版本信息

4. 安装插件

编辑器插件不是必需品,但差别很大。Angular 的模板是单独的 .html 文件,里面写的 *ngFor、[ngClass] 这些默认是没有提示的,装上语言服务插件之后,模板里能直接跳转到组件的属性定义,写错属性名当场标红。

编辑器中安装 Angular 相关插件

5. 安装chrome扩展

augury 是当年调 Angular 的浏览器扩展,地址是 https://augury.angular.io/ ,它能把当前页面的组件树画出来,点开某个组件可以看到它的输入属性、注入了哪些服务、变更检测的状态。排查「数据明明改了视图没动」这类问题的时候,比一路 console.log 快得多。

用 augury 查看 Angular 组件树结构

补一句时效性。augury 是针对 Ivy 之前的渲染器写的,Angular 切到 Ivy 之后它就不再适用了,官方后来另出了 Angular DevTools 扩展接替这个位置,功能上也是组件树加变更检测分析。具体从哪个版本开始换,以官方文档为准。

# 2.2 创建项目

环境好了就可以起项目了。ng new 会问你要不要路由、样式用 CSS 还是 SCSS,按需要选就行,选完它会自动跑一次依赖安装。

# 创建项目
ng new my-app

cd my-app

# 运行项目
ng serve --open
@前端进阶之旅: 代码已经复制到剪贴板

ng serve 起的是带热更新的开发服务器,默认端口 4200,--open 会顺手帮你把浏览器打开。这一步如果卡在依赖安装上,可以加 --skip-install 先把目录结构生成出来,再手动装依赖,后面第十章建路由项目的时候就是这么干的。

# 2.3 目录结构分析

ng new 一口气生成了几十个文件,第一次看会有点懵。其实真正日常会动的就那么几个,剩下的是配置和测试脚手架,知道它们存在就行。

Angular CLI 生成的项目目录结构总览

完整的文件说明可以参考官方的 https://www.angular.cn/guide/file-structure ,这里只挑重点讲。

app目录(重点)

app 目录是我们真正写代码的地方,业务代码全在这儿。一个 Angular 程序至少需要一个模块和一个组件,新建项目的时候 CLI 已经默认帮你生成好了,这也是 Angular 和 Vue 那种「一个 main.js 挂上去就行」最直观的区别,它一开始就强制你分模块。

app 目录下默认生成的组件与模块文件

先看 app.component.ts,这个文件表示一个组件。组件是 Angular 应用的基本构建单元,你可以把它理解成一段带着业务逻辑和数据的 Html。下面这张图是它的默认内容,我们逐行拆一下每部分在干什么。

app.component.ts 默认代码内容

/*这里是从Angular核心模块里面引入了component装饰器*/
import {Component} from '@angular/core';

/*用装饰器定义了一个组件以及组件的元数据  所有的组件都必须使用这个装饰器来注解*/
@Component({
  /*组件元数据  Angular会通过这里面的属性来渲染组件并执行逻辑
  * selector就是css选择器,表示这个组件可以通过app-root来调用,index.html中有个<app-root>Loading...</app-root>标签,这个标签用来展示该组件的内容
  *templateUrl  组件的模板,定义了组件的布局和内容
  *styleUrls   该模板引用那个css样式
  * */
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
/*AppComponent本来就是一个普通的typescript类,但是上面的组件元数据装饰器告诉Angular,AppComponent是一个组件,需要把一些元数据附加到这个类上,Angular就会把AppComponent当组件来处理*/
export class AppComponent {
  /*这个类实际上就是该组件的控制器,我们的业务逻辑就是在这个类中编写*/
  title = '学习Angular';
}
@前端进阶之旅: 代码已经复制到剪贴板

组件相关的概念

上面这段代码信息量不小,把它拆成三块看就清楚了。

第一块是组件元数据装饰器 @Component,简称组件装饰器,作用是告诉 Angular 框架该怎么处理一个普通的 TypeScript 类。它里面写的那些属性叫元数据,Angular 会读这些元数据来渲染组件、执行组件逻辑。selector 决定这个组件在别的模板里用什么标签调用,templateUrl 指向布局文件,styleUrls 指向样式文件。

第二块是模板 Template,也就是组件的外观。模板以 html 形式存在,长得很像普通 HTML,但可以用 Angular 的数据绑定语法把控制器里的数据渲染出来。

第三块是控制器 controller,就是被 @Component 装饰的那个普通 TypeScript 类。组件所有的属性和方法都挂在这里,绝大多数业务逻辑也写在这里。模板和控制器之间靠数据绑定通信,模板展示控制器的数据,控制器处理模板上冒出来的事件。

装饰器、模板、控制器是组件的必备要素。除此之外还有一些可选项,用到的时候再回来查:

  • 输入属性 @Input,用来接收外部传进来的数据。Angular 的程序结构本身就是一棵组件树,输入属性让数据能在这棵树上往下传
  • 提供器 providers,做依赖注入用的,第四章会展开
  • 生命周期钩子 LifeCycle Hooks,一个组件从创建到销毁会依次触发一串钩子,和 Android 里 Activity 的生命周期是同一个套路,第七章专门讲
  • 样式表,组件可以关联自己的样式,而且默认是有作用域隔离的
  • 动画 Animations,Angular 提供了独立的动画包,做淡入淡出这类跟组件状态挂钩的效果比手写 CSS class 切换清楚
  • 输出属性 @Output,用来往外抛事件,或者在组件之间共享数据
fe
  • 一、Angular 介绍
  • 二、Angular 环境搭建及创建项目
    • 2.1 环境搭建
    • 2.2 创建项目
    • 2.3 目录结构分析
    • 2.4 Angular cli
  • 三、Angular 组件及组件里的模板
    • 3.1 创建 Angular 组件
    • 3.2 Angular 绑定数据
    • 3.3 声明属性的几种方式
    • 3.4 绑定属性
    • 3.5 数据循环 *ngFor
    • 3.6 条件判断 *ngIf
    • 3.7 *ngSwitch
    • 3.8 事件绑定 (click)
    • 3.9 表单事件
    • 3.10 双向数据绑定
    • 3.11 [ngClass]、[ngStyle]
    • 3.12 管道
    • 3.13 实现一个人员登记表单-案例
    • 3.14 实现一个完整的ToDo-案例
    • 3.15 搜索缓存数据-案例
  • 四、Angular 中的服务
    • 4.1 服务
    • 4.2 改造上面的Todo、searchList
  • 五、Dom 操作以及@ViewChild、 执行 css3 动画
  • 六、Angular 父子组件以及组件之间通讯
    • 6.1 父组件给子组件传值-@input
    • 6.2 子组件通过@Output 触发父组件的方法(了解)
    • 6.3 父组件通过@ViewChild 主动获取子组 件的数据和方法
    • 6.4 非父子组件通讯
  • 七、Angular 中的生命周期函数
    • 7.1 Angular中的生命周期函数
    • 7.2 生命周期钩子详解
      • 7.2.1 constructor-掌握
      • 7.2.2 ngOnChanges()
      • 7.2.3 ngOnInit()–掌握
      • 7.2.4 ngDoCheck()
      • 7.2.5 ngAfterContentInit()
      • 7.2.6 ngAfterContentChecked()
      • 7.2.7 ngAfterViewInit()–掌握
      • 7.2.8 ngAfterViewChecked()
      • 7.2.9 ngOnDestroy()–掌握
  • 八、Rxjs 异步数据流编程
    • 8.1 Rxjs介绍
    • 8.2 Promise和RxJS处理异步对比
    • 8.3 Rxjs unsubscribe 取消订阅
    • 8.4 Rxjs 订阅后多次执行
    • 8.5 Angualr6.x之前使用Rxjs的工具函数 map filter
    • 8.6 Angualr6.x 以后 Rxjs6.x 的变化以及 使用
      • 8.6.1 Rxjs 的变化参考
    • 8.7 Rxjs 延迟执行
  • 九、Angular 中的数据交互(get jsonp post)
    • 9.1 Angular get 请求数据
    • 9.2 Angular post 提交数据
    • 9.3 Angular Jsonp 请求数据
    • 9.4 Angular 中使用第三方模块 axios 请求数据
  • 十、Angular 中的路由
    • 10.1 Angular 创建一个默认带路由的项目
    • 10.2 routerLink 跳转页面 默认路由
    • 10.3 routerLinkActive 设置routerLink 默认选中路由
    • 10.4 routerLink Get传递参数
    • 10.5 动态路由
    • 10.6 动态路由的 js 跳转
    • 10.7 路由 get 传值 js 跳转
    • 10.8 父子路由
  • 十一、更多参考
  • 总结
  • 参考

← 混合App之Ionic3完整实战小结 从环境搭建到打包上架Electron 构建跨平台桌面应用实战笔记 mac/windows/linux →