Angular 基础记录
Angular 基础
1.安装angular的脚手架(安装 过的可以忽略 )
npm install -g @angular/cli
卸载安装最新的 :
npm uninstall -g
npm install --save
全局安装 npm-upgrade
npm install -g npm-upgrade
--更新所有包
npm-upgrade
--更新指定包
npm-upgrade <package>
2.使用第三方库 npm-check
npm install -g npm-check
--全局安装 npm-check
--查询项目所有更新的包
npm-check -u
--检查全局有更新的包
npm-check -u -g如果提示 :无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\ng.ps1,因为在此系统上禁止运行脚本 则以管理员身份执行 Windows PowerShell, 执行以下指令
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
2.创建angular项目
ng new 项目名(下图为目录结构说明 )
注意 :由于国内安装 有些包可能会失败所以可以按以下方法添加 taobao的包源,来安装项目依赖包
执行以下的 就会有cnpm(注册 cnpm 的包源)
npm install -g cnpm --registry=https://registry.npm.taobao.org
创建项目时跳过 npm install(后面项目创建好可以手动执行), 这个是安装所需要包的命令所以一定会需要 .跳过是因为可以选择cnpm(淘宝的,要装个东西才有这命令) 命令来使用国内的源安装
ng new xxx --skip-install
启动项目 ng serve
启动后打开浏览器 ng serve –open
默认启动端口是4200 如果要指定可以用下面的命令
ng serve --port 4100
注意 (如果没有使用可以忽略,因为不是所有功能都用到它.如果页面加载慢可以看一下网络监控是不是加载不到资源导致的): 由于angular使用了google字体库,路径https://fonts.googleapis.com ,在国内访问不到.如果环境可以使用网络则可以在项目中搜索把该路径替换为 https://fonts.font.im ,这个路径是中国站的地址 ,主网站为 http://googlefonts.cn/ , 但如果不能访问外网则需要下载字体本地包然后修改引用.
3. 创建组件 (就是页面显示的内容,组件默认创建在 app目录下 )
ng g (这是创建命令,具体的指令 可以 运行该指令后看内容提示)
ngOnInit 方法是在页面刷新时触发 一次(只代表组件和指令初始化完.不代码页面dom加载 完成 , 如不含指令的元素在这里可以获取到但含指令的就获取不到了)
ngAfterViewInit 视图加截完成,dom在这里就一定完成了
4. 数据绑定 (绑定中如果值不用引号则表示是使用的声明的属性,和vue类似)
如 [title]=”’aaa’+dd” 则表名字符串 aaa+一个定义的属性 dd, 在定义属性,变量时最后指定类型(防止引用有些组件不支持不指定类型的方式 引起未知问题)
定义数据在当前组件的 组件名.component.ts ,如下图定义一个xxx属性.指定为string类型
constructor 是这个组件的构造函数
属性不加访问修饰符默认为 public 它的修改符有 共有,私有,被保护3种
在标签内绑定数据可以直接用{{xxx}} 如<div>{{xxx}}</div>
在标签属性上绑定数据 则属性要用[] 括起来 如 <div [title]="xxx"></div>
当在标签里显示html内容则需要给标签的innerHTML赋值(否则则按标签原样输出代码) 如<div [innerHTML]="xxx"></div>
5 . 指令(同个元素上不能写多个指令与版本有关):
*ngFor 如 <li *ngFor=”let item of arr”></li>,如果要获取索引则
<li *ngFor="let item of items; let i=index"></li>
Vscode中可安装 Angular N Snippets 在编码时就会有提示(N是版本号) 如下图
条件判断 *ngIf
*ngSwitch
样式绑定
[ngClass]=”{‘类名’:true,….}”
[ngStyle]=”{‘color’:’red’}”
[hidden] 隐藏显示某个内容
管道(也可以自定义) :
时间定义 ( | date :’格式’)
{{时间对象 | date:’yyyy-MM-dd’}}
6. 事件绑定用小括号括起来
如 (click)=”sss()” 定义sss方法如下,方法也能传入event和vue一样 sss($event)
事件绑定时也可以写表达式
7. 双向数据绑定
双向绑定只在form中才有效. 在使用之前需要先引用form组件
应用:
<input [(ngModel)]="name"/>
8.数据缓存(服务的应用,在angular中组件中无法相互访问,服务 大家都 可以方法)
注意 : 这里说的无法相互访问是原则上的.如果你把一个组件也注册到服务里依然是可以访问的.但很不建议这样做 ,这个访问规则也是这样只是原则上不能相互调
组件与组件不能相互调用(父子组件可以相互操作) ,组件可以调服务 ,服务不能调组件 , 服务间可以相互调用
1. 创建服务 默认在app目录下
ng g service 服务名(路径)
如 在sss目录下创建一个sms服务 ng g service sss/sms
添加服务后也需要在下面的文件里添加 引用.并注册在箭头的位置,注册后在其它组件中使用依然需要按下面引用的方法一样引用一次 ,才能使用(如下第二图)
9. angular中的DOM操作
1. 原生方法操作,按第三点说的操作dom元素应该在ngAfterViewInit 方法中进行.
2. 使用angular中的dom操作类ViewChild
1. 给dom对象起个名字用 # 如
<div #dnd>
</div>
2. 在引用里引用viewChild,然后通装饰器来获取如下图,注意这里依然建议在ngAfterViewInit去使用dom对象 ,
3. viewChild也可以直接获取出一个子组件, 和上面操作一致.通过装饰器取出来的就直接是子组件对象(区别上面获取原生dom 是在对象的nativeElement 属性上)
9. 父子组件 及 组件间的通讯
1. 父组件传值给子组件 @input,原则上任何内容都能传 如,父组件自己,方法,属性,对象 等
给子组件上绑定一个属性,并在子组件中引用Input ,通过Input装饰器来接收值,注意接受的变量名与写在父组件中接收的属性名一致.如下面的tstn , 这里要注意接收值的类型用any(目前 我使用的版本 用any以外的编译报错,说未初始化属性,给个初始值后是可以正常接收父组件传来的数据),使用时像用自己的属性一样通过 this.tstn调用 即可
2. 父中获取子组件的数据 (参考第9.中的 ViewChild)
3. 通过 Output进行父子交互
1. 像引用input一样添加 Output 和 EventEmitter 的引用
2. 在 子组件中实例化EventEmitter
3. 子通过调用 EventEmitter实例 的emit方法向父递交数据
4. 父在子组件标签上添加方法来接收子传传的数据 (绑定的属性要和子里实例化的EventEmitter的属性名一致)
4. 没有关系 的组件中数据交换 .一般使用 服务 或 localStorage
10. 生命周期 (https://angular.cn/guide/lifecycle-hooks)
以下按顺序执行,Init的加载时触发一次, Check的数据发生变化时就会触发一次(顺序1, 5,7,3),如果有父子传子的变更ngOnChanges 也会被触发
|
|
1 |
|
|
|
ngOnChanges() |
当 Angular 设置或重新设置数据绑定的输入属性时响应。 该方法接受当前和上一属性值的 SimpleChanges 对象 注意,这发生的非常频繁,所以你在这里执行的任何操作都会显著影响性能。 欲知详情,参阅本文档的使用变更检测钩子。 有父子传值时它才触发 |
在 ngOnInit() 之前以及所绑定的一个或多个输入属性的值发生变化时都会调用。 注意,如果你的组件没有输入,或者你使用它时没有提供任何输入,那么框架就不会调用 ngOnChanges()。 |
|
|
2 |
|
|
|
ngOnInit() |
在 Angular 第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。 欲知详情,参阅本文档中的初始化组件或指令。 |
在第一轮 ngOnChanges() 完成之后调用,只调用一次。 |
|
|
3 |
|
|
|
ngDoCheck() |
检测,并在发生 Angular 无法或不愿意自己检测的变化时作出反应。 欲知详情和范例,参阅本文档中的自定义变更检测。 |
紧跟在每次执行变更检测时的 ngOnChanges() 和 首次执行变更检测时的 ngOnInit() 后调用。 |
|
|
4 |
|
|
|
ngAfterContentInit() |
当 Angular 把外部内容投影进组件视图或指令所在的视图之后调用。 欲知详情和范例,参阅本文档中的响应内容中的变更。 |
第一次 ngDoCheck() 之后调用,只调用一次。 |
|
|
5 |
|
|
|
ngAfterContentChecked() |
每当 Angular 检查完被投影到组件或指令中的内容之后调用。 欲知详情和范例,参阅本文档中的响应被投影内容的变更。 |
ngAfterContentInit() 和每次 ngDoCheck() 之后调用 |
|
|
6 |
|
|
|
ngAfterViewInit() |
当 Angular 初始化完组件视图及其子视图或包含该指令的视图之后调用。 欲知详情和范例,参阅本文档中的响应视图变更。 |
第一次 ngAfterContentChecked() 之后调用,只调用一次。 |
|
|
7 |
|
|
|
ngAfterViewChecked() |
每当 Angular 做完组件视图和子视图或包含该指令的视图的变更检测之后调用。 |
ngAfterViewInit() 和每次 ngAfterContentChecked() 之后调用。 |
|
|
8 |
|
|
|
ngOnDestroy() |
每当 Angular 每次销毁指令/组件之前调用并清扫。 在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏。 欲知详情,参阅本文档中的在实例销毁时进行清理。 |
在 Angular 销毁指令或组件之前立即调用。 |
11. Angular中异步操作 Rxjs
添加引用
import {Observable} from 'rxjs'
如果需要使用工具还需要添加(才map和filter 两个工具举例)
import {map,filter} from 'rxjs/operators'
使用如下
注意. 在回调里可以传 {next:c=>{},error:err=>{},complete:()=>{}} 但是complete 在error被触发后不会触发
12. 与后台交互处理
1. get/post 请求 angular5 以后都 是使用HttpClientModule模块来实现的
2. 先引用HttpClientModule并注入到angular
3. 在需要使用的地方引用HttpClient,并在构造函数中注入(声明)
4. 如果需要跨域 可以使用本地代理实现 https://blog.csdn.net/changerjjlee/article/details/103833842
5. 也可以配置响应头
<add name="Access-Control-Allow-Origin" value="这里设置具体地址如 http://localhost:4200/" />
<add name="Access-Control-Allow-Credentials" value="true" />
<add name="Access-Control-Allow-Methods" value="GET,POST" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept, Authorization" />
13. 路由
1. 在创建项目时选择添加 路由
2.生成的项目中会多一个路径配置文件app-routing.module ,并在app.module 中注册路由模块
3. 路径配置,先引用组件,然后再做如下配置,当path:”**”时表示其它都未匹配到时选择的路由规则,这时可以设置
//没有匹配到其它路由则跳转到home
{path:'**',redirectTo:'home'}
//下面的也可以
{path:'',redirectTo:'/home',pathMatch:'full'}
4 . 使用时可以 http://根路径 /home 也可以在标签上写 routerLink 来实现 , routerLinkActive 表示如果当前是自己这个路径则添加 active的样式(active这里是指样式 名自己可以定义)
<a routerLink="/home" routerLinkActive=’active’></a>
5. 路径动态传值 (注意 routerlink 加中括号后面则跟一个表达式.不加则像上面一个跟一个字符串),
Get 传值
<a [routerLink]="[ '/path' ]" [queryParams]="{xx:2}" routerLinkActive="active">name</a>
要在组件里获取到传的值 .则需要添加 对router的引用如下
动态路径传值
路由配制改为: {path:'home/:xx',component:HomeComponent},
:xx 占位,表示这里有个参数名字叫xx,然后通过下面的方式 就会把nn传给xx 生成地址为 home/nn
<a [routerLink]="[ '/home','nn' ]" routerLinkActive="active">kkk</a>
组件内取值是和get取值 差不多只是属性不一样
this.r.params.subscribe(c=>{ })
6. js代码跳转
动态路由的跳转
需要引用Router,在构造函数中注入后, 直接用router进行跳转
import { Router } from '@angular/router'
router.navigate(['/home','nn'])
get传值的js跳转
除了Router 还需要引用 NavigationExtras (非必要,但参数要按下面对象格式来), 参考以下代码
import { Router, NavigationExtras } from '@angular/router'
var nav:NavigationExtras={
queryParams:{"xx":"nn"},
fragment:'anchor'
};
this.router.navigate(['/home'],nav);
7. 父子路由 (嵌套路由)
路由配置 加了一个children
{path:'home',component:HomeComponent ,
children:[
{path:'home1',component:HomeComponent}
]}
页面写法
<a routerLink="/home/home1" routerLinkActive="dd">name</a>
需要把子组件加载到父的某一个地方.只要添加 以下标签即可
<router-outlet></router-outlet>
8. 在主组件执行时需要获取当前执行的子组件的对象可以使用下面两个事件(参数就是子组件对象)
<router-outlet (activate)="onActivate($event)"></router-outlet>
<router-outlet (deactivate)="onDeactivate($event)"></router-outlet>
8. 样式添加 参考文献:https://codingdict.com/questions/18625
按官方说明添加样式后如 styleClass , 如果因为属性选择器的问题导致无法应用,可以尝试在写样式时添加 ::ng-deep 如下 (也可以在组件装饰器加上 encapsulation: ViewEncapsulation.None 使该组件的样式变成全局样式 ),
::ng-deep .CToolbar {
background-color: #14181b;
color: #fff;
.header_systemName {
font-size: 28px;
font-weight: 700;
}
.header_version {
padding-top: 8px;
}
}
生成
失败示例 :
原样式 写法
生成
9 使用Cookie
安装服务模块
npm install ngx-cookie-service --save
注册服务
import { CookieService } from 'ngx-cookie-service';
使用时注入服务然后
//cookie的存储
this.cookieService.set('key', val);
//cookie的读取
const val= this.cookieService.get("key");
10 编译时提示
initial exceeded maximum budget
则可以在angular. json中进行修改
"budgets": [
{
"type": "initial",
"maximumWarning": "10mb",
"maximumError": "10mb"
}
11. 组件懒加载,我们在实际应用中项目越做越大如果一次性加到前台则会变的很臃肿 这时候就需要用到懒加载( 惰性加载特性模块) https://angular.cn/guide/lazy-loading-ngmodules
简单的说 就是在创建组件时使用以下命名 替换原来的 ng g component 命令 为 ng generate module 名称 --route 名称 --module app.module 详细如下
- 首先明确什么样的组件不需要懒加载,即一请求网站就加载的组件 就不需要懒加载
- 具体操作
- 需要懒加载的组件添加时 改用 ng generate module 名称 --route 名称 --module app.module
- 生成的组件会多两个文件如下.
- 在配置路由的时候进行调整
- 由于懒加载的组件 不能使用到根组件中注册的那些组件 所以我添加了公共的共享module 大家在自己懒加载的组件的module文件里添加引用注册即可
注意 : 由于这里使用了共享模块.所以在添加比较公用的 组件库 组件时不需要添加到app.module的(因为在app.module里imports了 这个共享模块)imports 中 请添加到共享module中 如 (参考 :https://angular.cn/guide/sharing-ngmodules)
在共享模块中不要添加下面的引用, 因为下面两个模块在整个项目中只能引用一次. 在共享 模块中引用生成不报错.页面加载时js报错
import { BrowserModule } from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations'检查是否应用了懒加载.即在点击路由跳转时看下是否有如下的请求,正常不懒加载的跳转页面是没有页面请求的
Angular Material
- 按官方说明安装
- 所有的组件使用前都需要在app.component 里提前注册好后才能使用 如下图
如果需要阻止事件冒泡 可以使用 @tinkoff/ng-event-plugins 这个组件 直接在npm 里安装即可. 参考 : https://www.npmjs.com/package/@tinkoff/ng-event-plugins