angular入门
Angular1.Angular简单对比三大框架框架名称AngularReactVue优点1.良好的应用程序结构2.双向数据绑定3.指令、HTML模板4.可嵌入、注入、测试…1.速度快、模块化2.跨浏览器、兼容性好1.简单易学2.异步更新DOM,速度快3.组件复用高效…缺点1.入门容易,深入难2.官方文档基本只有api,无示例React(V)+ReactRouter+Flux才能构成完整应用1.新
Angular
1.Angular
简单对比三大框架
框架名称 | Angular | React | Vue |
---|---|---|---|
优点 | 1.良好的应用程序结构 2.双向数据绑定 3.指令、HTML模板 4.可嵌入、注入、测试… | 1.速度快、模块化 2.跨浏览器、兼容性好 | 1.简单易学 2.异步更新DOM,速度快 3.组件复用高效… |
缺点 | 1.入门容易,深入难 2.官方文档基本只有api,无示例 | React(V)+ReactRouter+Flux才能构成完整应用 | 1.新生儿,生态不够成熟 2.有关Vue的三方库较少 |
使用情况 | 较少 | 最多 | 较少 |
2.环境搭建
2.1安装node.js、npm
npm install -g cnpm --registry=https://registry.npm.taobao.org # cnpm可以更快下载包,推荐安装
2.2安装脚手架
npm install -g @angular/cli
2.3创建项目
ng new demo
2.4编译打开运行
ng serve --open
2.5项目结构介绍
- src
- app:组件和根模块
- karma.config.js:端到端测试文件
- polyfills.js:填充库,需要添加 (window as any).global = window
// app.module.ts
// 这个文件时angular的根模块,告诉angular如何组装应用
import { BrowserModule } from '@angular/platform-browser'; // 浏览器解析模块
import { NgModule } from '@angular/core'; // angular核心模块
import { AppComponent } from './app.component'; // 根组件
// NgModule装饰器,接受一个对象,告诉angular如何编译和启动应用
@NgModule({
declarations: [ // 配置当前模块运行的组件
AppComponent // 根组件
],
imports: [
BrowserModule // 当前项目依赖的其他模块
],
providers: [],// 配置当前项目所需要的其他服务
bootstrap: [AppComponent] // 指定应用的主视图(根组件),通过引导根AppModule来启动应用,一般是根组件
})
// 不需要暴露任何东西,因为没有模块引用根组件
export class AppModule { }
// app.component.ts
// 引入核心模块的component
import { Component } from '@angular/core';
@Component({
selector: 'app-root', // 组件的名称
templateUrl: './app.component.html', // html
styleUrls: ['./app.component.scss'] // css
})
export class AppComponent {
title = 'demo1'; // 暴露根组件
}
2.6创建自定义组件
会在app/components/
目录下创建news文件夹,包含组件的HTML、style、ts等文件
ng g component components/news
// app.module.ts
import { NewsComponent } from './components/news/news.component' // 引入自定义组件
@NgModule({
declarations: [ // 配置当前模块运行的组件
AppComponent, NewsComponent
],
// ...
})
// 然后在其他组件的HTML使用<app-news></app-news>即可
<!--app.component.html-->
<app-news></app-news>
<!--...-->
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QAkE1kBD-1608216905832)(image-20201215230155951.png)]
3.基本语法
3.1动态属性
<!-- [src]是动态属性,类似Vue中的 :src -->
<img class ="search" [src]="picUrl" alt="google" width="80px" height="32px">
3.2ngFor、ngSwitch
<!--ngFor、ngSwitch、ngIf、ngClass的用法-->
<!--ngFor用法-->
<div *ngFor="let item of lists;let key=index"> <!--lists是该组件的ts类中的属性,可以直接读取到,下同-->
<h4>{{item.title}}</h4>
<span style="color: lightcoral;">[{{key}}]</span>
<p>{{item.content}}</p>
</div>
<!--ngIf用法-->
<div *ngIf="showMore">
<h4>Common</h4>
</div>
<!--ngSwitch用法-->
<div [ngSwitch]="clickCount">
<div *ngSwitchCase="1">你居然打老子一巴掌</div>
<div *ngSwitchCase="2">你居然又打老子一巴掌</div>
<div *ngSwitchCase="3">你滚!</div>
<div *ngSwitchDefault>你还没挨老子!</div>
</div>
<!--ngClass、ngStyle用法-->
<div [ngSwitch]="clickCount" [ngClass]="{'red': clickCount===3}" [ngStyle]="{'font-size': (clickCount*3+16)+'px'}">
</div>
3.3管道
<!--管道用于对数据进行格式化,比如对一个obj使用json管道,就可以在前端页面以json格式显示,最常用处理时间格式-->
<span style="color: lightcoral;">{{today|date:'yyyy/MM/dd HH:mm:ss'}}</span>
<!--{{ obj | json }}-->
3.4事件
<!--点击事件用法-->
<button (click)="loadMore($event)">Load more</button>
<!--keydown keyup 等等-->
3.5双向数据绑定
// 双向数据绑定需要用到FormsModule模块,因此需要先引入,才能使用
// app.module.ts
import { FormsModule} from '@angular/forms'
@NgModule({
// ...
imports: [
BrowserModule,FormsModule // 当前项目依赖的其他模块
],
// ...
})
<input type="text" [(ngModel)]="keywords">-{{keywords}}
3.6服务
类似于Vuex或Mixin,封装了多个组件公共使用的东西
ng g service services/store
// app.module.ts 引入并配置服务
import { StoreService } from './services/store.service'; // 根组件
@NgModule({
// ...
providers: [StoreService],// 配置当前项目所需要的其他服务
// ...
})
// 例如 home 组件需要用(home.component.ts)
import { StoreService } from '../../services/store.service'; // 先引入
export class HomeComponent implements OnInit {
// ...
constructor(public store: StoreService) { // 使用public,在类其他地方就可以直接使用了
console.log(store);// 官方推荐使用
}
ngOnInit(): void {
// 这个是在指令和组件初始化完成,并不是DOM加载完成
// 页面每次刷新都会调用这个函数
}
// ...
}
3.7DOM操作
-
原生操作DOM(当然不建议)
<!--home.component.html--> <div id="box1" *ngIf="xxx"> 这个box在ngOnInit()是获取不到的! </div>
// home.component.ts ngOnInit(): void { // 这个是在指令和组件初始化完成,并不是DOM加载完成 // 页面每次刷新都会调用这个函数 } ngAfterViewInit():void{ // 这里才可以拿到所有的HTML元素(建议在这里操作DOM) let box:any = document.getElementById('box1') }
-
@ViewChild操作DOM
<!--home.component.html,需要给box设置#box--> <div #box> <h2>您好,angular!</h2> </div>
@ViewChild('box') box:any // 拿到id是box的HTML元素,并赋值给box ngAfterViewInit():void { console.log(this.box); this.box.nativeElement.style.letterSpacing='2px' }
3.8父子组件通信
-
(子调父)@Input:使得父组件不仅可以给子组件传值,还可以把父组件的方法、甚至父组件传给子组件
<!--home.component.html--> <app-news #homeNews [title]='title' [homeFun]='test' [homeComp]='this'></app-news>
// news.component.ts export class NewsComponent implements OnInit { @Input('title') title:any; @Input('homeFun') homeFun:any; @Input('homeComp') homeComp:any // ... ngAfterViewInit():void{ this.box.nativeElement.style.letterSpacing='2px' this.homeFun() // 调用home组件方法 console.log(this.homeComp); // 父组件 } // ...
-
(父调子)@ViewChild()
<!--home.component.html--> <app-news #homeNews></app-news>
// home.component.ts @ViewChild('homeNews') news: any // 拿到子组件 news ngAfterViewInit(): void { console.log(this.news.test()); // 逻辑处理 }
3.9生命周期函数
-
ngOnInit():用来请求数据
-
ngAfterViewInit():DOM操作
-
ngOnDestroy():离开某页面保存数据
3.10异步编程(Rxjs)
RxJS是一个异步编程的库,同时它通过observable序列来实现基于事件的编程(类似于Promise,但是比它更强大)
-
简单使用:先写一个request服务,然后组件调用
// request.service.ts(服务需要先在根组件引入和注册) import { Injectable } from '@angular/core'; import { Observable } from 'rxjs' // 1.引入类 @Injectable({ providedIn: 'root' }) export class RequestService { constructor() { } getRxjsData(): any { // 2.实例化一个对象,并写逻辑 return new Observable((observer: any) => { setTimeout(() => { var data = { name: 'yuwan', age: 22 } observer.next(data) // 成功调用 // observer.error(msg) 失败调用 }, 2000) }) } } // home.component.ts import { RequestService } from '../../services/request.service'; // 引入服务 @Component({ selector: 'app-home', templateUrl: './home.component.html', styleUrls: ['./home.component.scss'] }) export class HomeComponent implements OnInit { // ... constructor(public request: RequestService) { } ngOnInit(): void { var resp=this.request.getRxjsData() // 请求数据 resp.subscribe((data)=>{ console.log(data); // 获取数据 }) } // ... }
-
取消订阅:即撤销发送请求(Promise是无法实现的)
// ... var opt=resp.subscribe((data)=>{ console.log(data); }) opt.unsubscribe() // 取消逻辑,例如一秒后取消发送
-
多次执行:订阅后,可多次执行(Promise是无法实现的)
// request.service.ts getRxjsData(): any { return new Observable((observer: any) => { let count=0 setInterval(() => { count++ observer.next(count) // 成功调用 // observer.error(msg) 失败调用 }, 2000) }) } // ... var opt=resp.subscribe((data)=>{ console.log(data); // 会2秒执行一次 }) // ...
-
处理数据:如上所示,如果要打印2,4,6…,需要处理数据(管道)
import { map, filter } from 'rxjs/operators' ngOnInit(): void { var resp = this.request.getRxjsNum() // 先设置管道过滤再打印数据,filter、map resp.pipe(filter((val: any) => { if (val % 2 == 0) { return true } })).subscribe(data => { console.log(data); }) }
3.11数据交互(和服务器打交道)
angular可通过自带与服务器交互的模块HttpClientModule
、jsonp(可解决跨域)
、axios第三方库
等方式
jsonp原理:大概是传一个回调函数去服务端,然后执行拿到数据后,再返回,url格式如http://www.xxx.com/api/goodslist?callback=xxx
// app.module.ts
import { HttpClientModule,HttpClientJsonpModule} from '@angular/common/http' // 引入
@NgModule({
// ...
imports: [
HttpClientModule,HttpClientJsonpModule // 当前项目依赖的其他模块
],
// ...
})
// home.component.ts
import { HttpClient,HttpHeaders } from '@angular/common/http' // 引入这个服务
export class HomeComponent implements OnInit {
// ...
constructor(public http:HttpClient ) {} // 实例化
getData():void{ // get方法
this.http.get('http://a.itying.com/api/productlist').subscribe(data=>{
console.log(data);
})
}
postData(): void { // post方法
var headOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
}
this.http.post('url', { username: 'yuwan', password: '123456' }, headOptions).subscribe(...)
}
getJsonPData(): void { // jsonp方式,其中第二个参数:cb或者callback 由服务端决定
this.http.jsonp('url', 'callback').subscribe(resp => {
console.log(resp);
})
}
// ...
}
3.12路由
创建项目时,选择安装路由,基本只需要在routes里更改,然后自定义组件即可
<style>
.router-link-active{
color:red
}
</style>
<!--导航链接 -->
<span style="margin-left:5px"><a [routerLink]="['/home']" routerLinkActive="router-link-active" >Home</a></span>
<span style="margin-left:5px"><a [routerLink]="['/about']" routerLinkActive="router-link-active" >about</a></span>
// app-routing.module.ts
import { HomeComponent } from './components/home/home.component';
import { AboutComponent } from './components/about/about.component';
const routes: Routes = [
{
path: 'home',
component: HomeComponent
},
{
path: 'about',
component: AboutComponent
},
{ // 匹配不到路由的时候,默认重定向到 home
path: '**',
redirectTo: 'home'
},
];
普通路由传参
<!--home.component.html-->
<a [routerLink]="['/news']" [queryParams]='{aid:123}'>点我跳转</a>
// news.component.ts
import { ActivatedRoute } from '@angular/router'
export class NewsComponent implements OnInit {
constructor(public activeRoute: ActivatedRoute) { }
ngOnInit(): void {
this.activeRoute.queryParams.subscribe(data => {
console.log(data);
})
}
}
动态路由传参
<!--home.component.html-->
<a [routerLink]="['/news/',123]" >点我跳转</a> <!--传送参数-->
// app-routing.module.ts
const routes: Routes = [
// ...
{
path: 'news/:aid',
component: NewsComponent
}
// ...
];
// news.component.ts
export class NewsComponent implements OnInit {
constructor(public activeRoute: ActivatedRoute) { }
ngOnInit(): void {
this.activeRoute.params.subscribe(data=>{ // 接收参数
console.log(data);
})
}
}
普通路由跳转和动态路由跳转
import { Router,NavigationExtras } from '@angular/router'
export class NewsComponent implements OnInit {
// ...
jump():void{
this.router.navigate(['/news/','1234']) // 动态路由跳转
this.router.navigate(['/home']) // 普通路由跳转
}
jump2():void{ // get方式跳转
let queryParams:NavigationExtras={
queryParams:{
'aid':'1233'
}
}
this.router.navigate(['/news'],queryParams)
}
}
嵌套路由
先创建相关组件,再修改app-routing.module.ts
ng g component components/service/request
ng g component components/service/state
// app-routing.module.ts
import { ServiceComponent } from './components/service/service.component';
import { RequestComponent } from './components/service/request/request.component';
import { StateComponent } from './components/service/state/state.component';
{
path: 'service',
component: ServiceComponent,
children: [
{
path: 'request',
component: RequestComponent
},
{
path: 'state',
component: StateComponent
}
]
},
<!--home.component.html-->
<a [routerLink]="['/service/request']">跳转request</a>
<a [routerLink]="['/service/state']" >跳转state</a>
<div>
<router-outlet></router-outlet>
</div>
更多推荐
所有评论(0)