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