Angular
what?
是一个针对中大型SPA的框架
why?
①采用了组件化的开发方式,非常方便描述app,代码的可读性比较好
②angular采用的开发语言是:TypeScript
ts是es6的超集
③采用了性能更高的工具,让开发和维护变得更简单
how
搭建:
步骤1:保证npm版本
安装最新版本的8.11.4 node的包
步骤2:全局安装Angular的cli工具
npm i -g @angular/cli
步骤3:通过cli创建一个angular的模板项目
ng new myProject
cd myProject
npm start
八大核心概念:
模块:是Angular的基本组成部分,就是一个容器,在该容器中指定要用到的组件、管道‘、自定义指令
组件:一个可被反复使用的,带有特定功能的视图
模板:html标签+自定义组件标签,构成组件的内容
绑定: 事件绑定、属性绑定、双向数据绑定
指令: 在 Angular 中有三种类型的指令:
组件 — 拥有模板的指令
结构型指令 — 通过添加和移除 DOM 元素改变 DOM 布局的指令
属性型指令 — 改变元素、组件或其它指令的外观和行为的指令。
管道:
将数据做筛选、过滤、格式化更好的呈现出来
服务
依赖注入
1 组件的创建和使用
ng g component demo01
①在src/app/创建一个文件夹demo01,在该文件夹中创建一个4个文件,有类,有样式,有模板
②在src/app/app.module.ts
找到了模块的配置文件,将创建的Demo01Component引入并声明
2 angular基本语法
{{}}
*ngFor
*ngIf
ngSwitch *ngSwitchCase *ngSwitchDefault
() //事件绑定
[] //属性绑定
[(ngModel)] -->让根模块依赖于表单模块 //双向数据绑定
3 angular组件间通讯
5.3.1 父与子通信
props down
步骤1:调用子组件时 通过属性传值
<son myTitle='123'></son>
步骤2:子组件接收数据
import {Input} from '@angular/core'
@Input() myTitle=""
this.myTitle
5.3.2 子与父通信
events up
步骤1:事件绑定
<son (myEvent)="rcvMsg($event)"></son>
步骤2:事件触发
import {EventEmitter,Output} from '@angular/core'
@Output() myEvent = new EventEmitter()
this.myEvent.emit(123);
5.3.3 兄弟通信
比如Main是由A和B构成,A想传数据给B
分两步来处理:
A将数据传给Main
Main将数据传给B
4 angular处理远程服务器端的通信工作
①找到app.module.ts
import {HttpClientModule} from '@angular/common/http'
@NgModule({
imports:[HttpClientModule]
})
让当前根模块支持使用HttpClient模块,组件才可以发网络请求
②组件中调用HttpClient
import {HttpClient} from '@angular/common/http'
constructor(private http:HttpClient){
}
this.http.get/post/put/delete(url).subscribe((result)=>{
//result就是服务器端返回的结果
})
5 angular路由模块
路由模块:建立起url和组件之间的映射关系
1、基本用法:
①app.module.ts 引入RouterModule,Routes两个类
import {RouterModule,Routes} from '@angular/router'
②指定盛放组件的容器
<router-outlet></router-outlet>
③创建app所需要用到的组件
④配置路由
const myRoutes:Routes = [
{path:'',component:**},
{}
]
⑤调用路由
@NgModule({
imports:[RouterModule.forRoot(myRoutes)]
})
关于路由基本配置的扩展:
考虑将路由的设置单独的放在一个模块中来实现,来避免让根模块过于臃肿!
①在app-routing/app-routing.module.ts中引入依赖 RouterModule Routes
②指定盛放组件容器
③创建要用到的组件
④配置路由
⑤调用路由
⑥让根模块依赖于自定义的路由模块
2、导航
跳转
方案1:js
//js 方式1
this.myRouter.navigateByUrl("register")
//js 方式2
this.myRouter.navigate(['register'])
方案2:指令
<a routerLink="register">跳转到注册页面</a>
3、传参
①明确发送方和接收方
②配置接收方的路由地址,接收参数
[{path:'main'}]==>[{path:'main/:id'}]
import {ActivatedRoute} from '@angular/router'
constructor(private acRoute:ActivatedRoute){}
this.acRoute.params.subscribe((result)=>{
//result就是发送来的数据
})
③发送参数
this.myRouter.navigate(['main',123])
this.myRouter.navigateByUrl('main/123')
<a [routerLink]="'main/'+uname">登录</a>
4、嵌套
路由嵌套:在一个路由对象中 嵌套其它的路由对象;借助于children
作用:让SPA的某些路由更灵活
举例:
准备一个demo05-mail,在这个组件中嵌套demo05-inbox/demo05-outbox
①给demo05-mail这个组件配置路由对象,准备一个容器用来盛放要嵌套的组件
<router-outlet></router-outlet>
②给收件箱和发件箱配置路由为(demo05-mail所对应的子路由)
{
path:'mail',
component:MailComponent,
children:[
{},
{}
]
}
5、守卫
router guard
在app中有些页面是需要登录或者鉴权之后才可以访问的,此时它就需要保护,通过路由守卫进行保护
demo05-admin
步骤1: 创建一个service 来实现一个接口CanActivate
步骤2: 在根模块中给service指定provider
步骤3:在路由词典,找到要保护的路由对象,调用创建好的路由守卫
import {AdminGuardService} from '**'
{
path:'admin',
component:AdminComponent,
canActivate:[AdminGuardService]
}
6 angular管道
管道:有些时候称之为过滤器,将原数数据通过筛选、过滤、格式化 更合理的将数据渲染出来;管道的本质就是一个有参数又返回值的方法
<any>{{expression | 过滤器:参数1:参数2}}</any>
内置管道:
uppercase/lowercase
currency
json
date
percent
slice
自定义管道:
ng g pipe my-pipe
(本质:实现一个接口类 PipeTransform,实现一个方法:transform有参数有返回值)
export class MyPipe implements PipeTransform {
trnasform(value:any,...args:any[]){
//value就是通过管道之前的表达式执行所传来的数据
//args是一个数组,是在调用管道时,传来的参数
}
}
{{expression | myPipe}}
7 angular服务的创建和使用
创建:
将复用的数据和方法 封装在一个服务类中,以方便复用
装饰器
@Injectable
使用:
准备工作:
方案1:指定providers(模块或者组件)
方案2:@Injectable({
providedIn:'root'
})//它的根注入器要负责调用,来创建一个服务实例,并让它在整个应用中都是可用的