|
本文系参考B站大地老师angular教学视频总结:
第一讲 ⦁ angular前提准备: ⦁ typescript入门教程:https://www.itying.com/goods-905.html ⦁ angular环境搭建: ⦁ node.js ⦁ 若需要的话,安装淘宝镜像 ⦁ Angular脚手架安装(只需安装一次):npm install -g @angular/cli (终端输入:ngv;检验angular脚手架是否安装成功) ⦁ 创建angular项目 ⦁ 找到要创建项目的文件目录 ⦁ 创建命令语句:ng new 项目名称(直接安装)/ ng new 项目名称 --skip-install (不安装依赖) ⦁ 运行项目:ng serve –open( ng serve 即可启动项目 --open是打开默认浏览器)
第二讲 1.angular目录讲解 ⦁ app.modules.ts(引入组件)  2)创建组件命令:ng g component components/news (在components文件夹里面创建news组件) / ng g c components/news(简写) 3)绑定数据:在ts文件的NewComponent implements onInit中定义属性,使用属性在html文件中以双花括号的形式
第三讲: ⦁ 组件定义属性 ⦁ 推荐写法: private 数据类型 = 值 注:声明属性的几种方式 Public 公有(默认)可以再当前类里面使用,也可以在类外面使用 Protected 保护类型 他只要在当前类和他的子类可以访问 Private 私有 只有在当前类才可以访问到这个属性 ⦁ 组件中获取/修改属性:在函数中 ⦁ 数据循环(显示索引):<li *ngFor=“let item of arr;let key=index”>{{item}}</li> 第四讲: ⦁ 引入本地图片:<img src=”assets/images/xxx.jpg” /> ⦁ 引入远程图片:<img [src]=”pictureUrl” /> ⦁ 组件内的条件判断:*ngIf=“flag”(没有else) ⦁ Switch条件判断:如下 <ul [ngSwitch] = “score”> <li *ngSwitchCase=”1”>已支付</li> <li *ngSwitchCase=”2”>未支付</li> <li *ngSwitchCase=”3”>已取消</li> <li *ngSwitchDefault >无效</li> </ul> ⦁ 绑定属性: <div [ngClass]=“{‘red’:flag,’blue’:!flag}”> <div [ngStyle]=”{‘width’:’100px’}”> ⦁ 管道:例: {{todaty | data:‘yyyy-MM-dd HH:mm ss’}} ⦁ 事件/方法: 1)定义方法:写在与constructor函数平行的地方,方法之间不需要加逗号 2)执行方法:(click)= “getData()” 3)键盘事件:(keydown)= “keydown($event)“ Keydown(e){ Console.log(e.target) // 获取当前事件对象 Console.log(e.keyCode) // 获取当前事件对象的键盘码 } ⦁ 双向数据绑定(mvvm只是针对表单) ⦁ 首先在app.module.ts中引入 FormModule Import {FormsModule} from ‘@angular/forms’ ⦁ 引入某模块后,在app.module.ts中声明模块 ⦁ 使用:<input [(ngModel)]=”keyWords“ /> 4)备注:[ ]表示绑定属性,( )表示绑定事件
第七讲: angular中的服务 ⦁ 创建服务命令:ng g service 服务名称 创建服务到指定目录下:ng g service services/storage(在app的services文件夹下面创建一个storage服务 ⦁ 首先在app.module.ts中引入并声明服务; ⦁ 在组件中需要引用服务的话,需要在组件中再次引入,并且在constructor函数中初始化并通过this.xxx使用服务 ⦁ 备注:组件可以调用服务,但是服务不能调用组件,服务与服务之间又可以相互调用; 第八讲: angular中的dom操作 ⦁ ngOnInit:组件和指令初始化完成的钩子函数,并不是真正的dom加载完成 ⦁ ngAfterViewInit:视图加载完成的钩子函数 ⦁ angular获取dom节点: ⦁ 在html中给节点命名:<div #myBox>获取dom节点</div> ⦁ 在ts中引入ViewChild,并在类里面使用ViewChild装饰器获取节点: @ViewChild('myBox') myBox: any; ⦁ 在ts的ngAfterViewInit生命周期中获取dom:this.myBox.nativeElement ⦁ ViewChild同样可以获取子组件实例,然后就可以调用子组件的方法 第九讲: 父子组件及组件通信 1.父传子: 1)父组件调用子组件的时候传入数据: <app-header [newsMsg]="newsMsg" [newsFn]="newsFn" ></app-header> ⦁ 子组件引入import模块 import {Component, OnInit, Input} from '@angular/core'; ⦁ 组件@input接收父组件传过来的数据 export class HeaderComponent implements OnInit { @Input () newsMsg: any; @Input () newsFn: any; Constructor () {} ngOnInit (): void {} } 4)子组件使用父组件的数据: this. newsMsg; this. newsFn () 2. 子传父: ViewChild(同angular获取dom节点的方式一致) 3.组件之间其他通信方法:(子组件触发父组件的方法,并向父组件传参) 1)子组件引入Output和EventEmitter import {Component, OnInit, Input, Output, EventEmitter} from '@angular/core'; ⦁ 子组件中实例化EventEmitter @Output () private outer = new EventEmitter (); 3)子组件中写一个方法:通过EventEmitter对象outer实例广播数据 sendParent () { this.outer.emit ('我要触发父组件方法') } 以下是触发时机: <button (click)="sendParent()">广播数据给父组件</button> ⦁ 父组件调用子组件的时候,定义接收事件,outer就是子组件的EventEmitter对象outer <app-header (outer)="getHeader($event)"></app-header> ⦁ 父组件接受到数据就会调用组件的getHeader方法,此时能拿到子组件传递的数据。 getHeader(msg) { alert( msg +'我是父组件中的方法') } 备注:点击子组件中的button就能触发父组件中的getHeader方法,msg就是子组件传过来的值。 第十讲 angular的生命周期函数(8个):就是组件创建、组件更新、组件销毁的时候会触发的一系列的方法。 1.ngOnChanges ( ) : 当angular(重新)设置数据绑定输入属性时,(或者说是在父子组件传参发生改变时响应)。第一次触发在ngOnInit 之前。(若无父子组件之间传值,第一次不触发) 2.ngOnInit ( ): 在angular第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。(请求数据一般在这个周期中); 第一轮ngOnChanges ( )完成之后调用,只调用一次。 3.ngDocheck ( ): 检测,并在发生angular无法或不愿意自己检测的变化时做出反应(在此处检测数据,并自定义一些操作); 在每个angular变更检测周期中调用,ngOnChanges()和ngOnInit()之后。 4.ngAfterContentInit ( ):当把内容投影进组件之后调用(组件触发的时候调用)第一次ngDocheck()之后调用,只调用一次 5.ngAfterContentChecked ( ): 检测,每次完成被投影组件内容的变更检测之后调用,(组件完成后做一些自定义的操作)。 6.ngAfterViewInit():初始化完组件视图的变更检测之后调用,ngAfterViewInit()和每次ngAfterContentChecked ()之后调用 7.ngAfterViewChecked ():每次做完组件视图和子视图的变更检测之后调用。ngAfterViewInit()和每次ngAfterContentChecked()之后调用。 8.ngOnDestroy ():在angular销毁指令/组件之前调用 备注:页面加载各个钩子函数的执行顺序如下: ⦁ construct构造函数执行:除了使用简单的值对局部变量进行初始化之外,什么都不应该做 ⦁ ngOnChanges执行:(若不涉及父子组件传值,该钩子函数不执行) ⦁ ngOnInit执行:一般在此请求数据 ⦁ ngDocheck 执行,检测,或者做一些自定义的操作 ⦁ ngAfterContentInit执行:把内容投影近组件之后 ⦁ ngAfterContentCheck 执行:每次完成被投影组件内容的变更检测之后调用 ⦁ ngAfterViewInit 执行:初始化完组件视图及其子视图之后(dom操作在此处) ⦁ ngAfterViewCheckd 执行:每次做完组件视图和子视图的变更检测之后调用 ⦁ ngOnDestroy 执行:销毁组件时(可以在这里做一些保存的操作)
第十一讲:rxjs的简单介绍 ⦁ 描述:RxJS是ReactiveX编成理念的JavaScript版本,来自微软,它是一种针对异步数据流的编程或者叫响应式扩展编程。 ⦁ 常见的异步编程的几种方法: ⦁ 回调函数 ⦁ 事件监听/发布订阅 ⦁ Promise ⦁ Rxjs 定义方法: import { Observable } from 'rxjs' getRxjsData () { return new Observable(observer=>{ setTimeout (() => { let name = '王五' observer.next (name) // observer.error('失败') },2000) }) } 使用方法: this.request.getRxjsData ().subscribe(data=> { console.log(data) }) 备注:从上述例子中可以看出promise和rxjs的用法基本相似,但其实rxjs比promise要强大很多:比如rxjs中可以中途撤回,可以发射多个值,提供了多种工具函数等。 1)rxjs使用之取消订阅: let streem = this. request. getRxjsData(); let dele = streem. Subscribe (data=> { console.log(data) }) setTimeout (()=> { dele. unsubscribe(); // 取消订阅 })
2)rxjs执行多次 定义方法: getSetIntervalRxjsData() { let count = 0 return new Observable(observer=>{ setInterval(()=>{ count++; let name = '赵六'+count observer.next(name) // observer.error('失败') },1000) }) } 使用方法: this.request.getSetIntervalRxjsData().subscribe(data=>{ console.log(data) }) 3)rxjs工具函数(filter) 例:map和filter 定义方法: getSetIntervalRxjsNum() { let count = 0 return new Observable(observer=>{ setInterval(()=>{ count++; observer.next(count); },1000) }) } 执行方法: import {map, filter} from 'rxjs/operators' this.request.getSetIntervalRxjsNum().pipe( // 管道 filter((value)=>{ // 过滤 if(Number(value)%2 == 0){ return true } }) ).subscribe(data=>{ console.log(data) // 只打印偶数 }) 例:throttleTime(rxjs延迟执行) import { Observable, fromEvent }from ‘rxjs’ import { map, filter, throttleTime } from ‘rxjs/operators’ var button = document.querySelector(‘button‘) fromEvent (button, ‘click’). pipe ( throttleTime (1000) ). subscribe (() =>console.log(‘clicked’));
第十二讲:angular请求数据相关 1.angular内置模块根据不同需求引入不同请求模块 Angular获取服务器数据(get,post等) 在app.module.ts中引入HttpClientModule并注入 Import {HttpClientMoule} from ‘@angular/common/http’ Imports:[BrowserModule, HttpClientMoule ] Jsonp获取服务器数据:(jsonp) 在app.module.ts中引入HttpClientModule、HttpClientJsonpMoudle并注入 Import {HttpClientMoule, HttpClientJsonpMoudle} from ‘@angular/common/http’ Imports:[BrowserModule, HttpClientMoule, HttpClientJsonpMoudle ]
请求数据 1) get方法, 在用到的地方引入HttpClient,并在构造函数声明 Import {HttpClient} from ‘@angular/common/http’ constructor (private http: HttpClient) {}
let api = ‘http://a.itying.com/api/productlist’, this.http.get(api). subscribe (res => { console.log(res) }) 2)post方法 在用到的地方需要引入HttpClient、HttpHeaders import {HttpClient, HttpHeaders} from ‘@angular/common/http’ constructor (private http: HttpClient) {} 手动设置请求类型: const httpOptions = { headers: new HttpHeaders({‘Content-Type‘: ‘application/json’}) } let api = ‘http://127.0.0.1:3000/doLogin’ this.http.post(api, {username: ‘张三‘,age: ‘20’},httpOptions).subscribe(res => { console.log(res) } 注:以上两种方法会存在跨域问题,需要服务器允许跨域 3)jsonp请求(服务器需要支持jsonp) 在用到的地方需要引入HttpClient、HttpHeaders import {HttpClient, HttpHeaders} from ‘@angular/common/http’ constructor (private http: HttpClient) {} let api = ‘http://127.0.0.1:3000/doLogin?callback=xxx’ let apis = ‘http://127.0.0.1:3000/doLogin?cb=xxx’(参数cb或者callback名由服务器定义) this.http.jsonp (api,’callback’).subscribe(res => {} 2.外部服务器请求 1)安装插件:npm install axios –save 2)在封装服务的文件中(如:httpservice.service.ts)引入axios,并封装方法 Import axios from axios 例:axiosGet(api){ return newPromise((resolve,reject)=>{ axios.get(api).then(res=>{ resolve(res) }); }) } 3)在app.module.ts中引入服务并申明 import {HttpserviceService} from ‘@/service/httpservice.service’ providers:[HttpserviceService] 4)在组件中使用服务:同样需要引入服务并申明,再在方法中使用 import {HttpserviceService} from ‘@/service/httpservice.service’ constructor (private httpService: HttpserviceService) {} getAxiosData(){ let api=www.baidu.com this.httpService.axiosGet(api).then(data=>{ console.log(data) }) }
第十三讲 ⦁ 路由就是根据不同的url地址,动态地让根组件挂载其他组件,来实现一个单页面应用 ⦁ 配置路由 ⦁ 创建项目的时候选择带路由 ⦁ 在项目中创建组件 ⦁ 在app.module.ts中引入组件并声明 ⦁ 在app-routing.moudule.ts中引入组件并配置路由,配置写法如下: const routes: Routes = [ {path: 'home', component: HomeComponent} ]; ⦁ 在app.component.html中写上<router-outlet></router-outlet>,然后本地访问: localhost:4200/home 就能显示home组件 ⦁ 路由跳转 ⦁ 使用routerLink跳转 <a [routerLink]="['/home']">首页</a> ⦁ 路由重定向(匹配默认路由):在routes: Routes中加上 {path: '**', redirectTo: 'home'}, ⦁ routerlink选中路由增加默认样式(类名可自定义): <a [routerLink]="['/home']" routerLinkActive="active">首页</a> 例:让选中a标签字体变成红色 .active { color: red; 4.实际项目中根路由中会引入模块 第十四讲 路由跳转传值: 1.get传值(使用queryParams绑定,值为object类型): 1)传值:<a [routerLink]="[ '/newsContent']" [queryParams]="{aid: key}"> {{item}} </a> 2)接收: (1)在接收的页面引入ActivedRoute : ActivedRoute import {ActivatedRoute} from '@angular/router'; (2)在需要接收的页面初始化(在constructor函数中): Constructor (private route: ActivatedRoute) {} (3)获取路由参数: this. route. queryParams. subscribe(data=>{ console.log(data) //data是一个object对象 }) 2.动态路由 1)路由的定义与普通路由不同(在path后面绑定动态的参数名): {path: 'NewsContent/:aid', component: NewsContentComponent}, 2)传值(要传的动态参数就放在路径后面): <a [routerLink]="[ '/NewsContent/', key]"> {{item}} </a> ⦁ 接收: (1)在接收的页面引入ActivedRoute : ActivedRoute import {ActivatedRoute} from '@angular/router'; (2)在需要接收的页面初始化(在constructor函数中): Constructor (private route: ActivatedRoute) {} (3)获取路由参数: this. route. params. subscribe(data=>{ console.log(data) //data是一个object对象 })
3.get传值js跳转 ⦁ 传值: (1) 引入Router import {Router, NavigationExtras} from '@angular/router'; ⦁ 初始化Router实例 Constructor (private router: Router) {} ⦁ js跳转 goProDetail () { let Params: NavigationExtras = { queryParams: {'pid': 'wuhua'} } this. router. navigate(['/NewsContent/'], Params) } 备注:Params不做NavigationExtras类型断言也可以传参,但是进行类型断言的写法更标准 2)接收:方法与a标签get传值路由跳转相同,这里就不赘述了
4.动态路由的js跳转 1)路由的定义与普通路由不同(在path后面绑定动态的参数名): {path: 'NewsContent/:aid', component: NewsContentComponent}, 2)传值(要传的动态参数就放在路径后面): ⦁ 引入Router import {Router} from '@angular/router'; ⦁ 初始化Router实例 Constructor (private router: Router) {} ⦁ js路由跳转 goProDetail () { this.router.navigate(['/NewsContent/', '1234']) } ⦁ 接收:方法与a标签动态路由相同,这里就不赘述了
第十五讲 Angular的嵌套路由:父子路由 ⦁ 创建组件并引入到app-routing.module.ts(方法同普通路由一致) ⦁ 在父路由中的children中配置子路由,如下所示:
⦁ 使用子路由: ⦁ 在父路由的页面加上a标签或者在方法中用js跳转: ⦁ 在父路由页面使用<router-outlet></router-outlet>展示子路由 如下图所示: 第十七讲 Angular的内置模块以及自定义模块: ⦁ 内置模块: 1)@angular/core 核心模块 2)@angular/common 通用模块 3)@angular/forms 表单模块 4)@angular/http 网络模块 5)更多其他模块 2.自定义模块(项目较大/组件较多时会导致加载变慢,此时需要用到自定义模块) 1)创建模块和组件: ng g module modules/user(在modules目录下面创建user模块) 简写:ng g m moudules/user 2)自定义模块要把需要暴露出去的组件exports出去 exports:[UserComponent], // 暴露组件,让其他模块可以使用 ⦁ 根模块(app.module.ts)中需要引入并申明 import { UserModule } from './modules/user/user.module' imports: [UserModule], ⦁ 根组件直接使用模块中暴露出来的组件 第十八讲: 路由模块实现懒加载 1).创建模块(自动生成当前模块的路由文件): ng g m modules/user/ --routing 2)在当前模块的路由文件(user-routing.module.ts)中引入该模块的根组件,并配置当前模块的路由 import {userComponent} from ‘./user.component’ ; const routes: Routes = [ {path:’’, component: userComponent} ] 3)在根模块(app.module)的路由文件(app-routing.module.ts)中设置模块的懒加载 const routes:Routes = [ {path: ‘user’, loadChildren:’./module/user/user.module#UserModule’}, // 写法1 {path:‘product’,loadChildren:()=>import(‘@pages/product/product.module’).then(m=>m.ProductModule)}, // 写法2 {path:‘**‘,redirectTo:’user’} ]
来源:https://www.cnblogs.com/wuhua/p/14084326.html |