前言
本文档假设你已经熟悉了 HTML,CSS,[JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) 和来自 [最新标准](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Language_Resources) 的一些知识,比如 [类](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) 和 [模块](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)。 下列代码范例都是用最新版本的 [TypeScript](https://www.typescriptlang.org/) 写的。 大多数 Angular 代码都只能用最新的 JavaScript 编写,它会用 [类型](https://www.typescriptlang.org/docs/handbook/classes.html) 实现依赖注入,还会用[装饰器](https://www.typescriptlang.org/docs/handbook/decorators.html)来提供元数据。<br /> Angular 是一个用 HTML 和 TypeScript 构建客户端应用的平台与框架。 Angular 本身就是用 TypeScript 写成的。它将核心功能和可选功能作为一组 TypeScript 库进行实现,你可以把它们导入你的应用中.<br /> 涵盖了组件、模板语法、路由、服务以及通过 HTTP 访问数据等,但是格式更简单,且遵循了绝大部分最佳践。<br />
开启hello world
//创建一个项目(用powerShell创建)
ng new xxx
//启动项目 (终端)
ng serve
打开文件项目
删除.html 所有代码 只剩hello world 开启服务
一、基本入门
基础知识
1-1 双向绑定 ngModel
注册
import {FormsModule} from '@angular/forms';
imports: [
BrowserModule,
FormsModule,
],
1-2 (change)
<input type="text"
(change)="handleChange($event)"/>
{{msg}}
handleChange(){
console.log(this.checked)
}
1-3 (ngModelChange)
[(ngModel)]="checked"
(ngModelChange)="handleChange($event)"/>
export class HeaderComponent implements OnInit {
public msg:string = "hello world";
public checked:boolean = true;
...
handleChange(){
console.log(this.checked)
}
1-4 获取DOM / 生命周期获取DOM
第一种:
ngOnInit() {
var app:any = document.getElementById("app");
app.style.color="red"
console.log(app)
}
第二种 生命周期获取dom
<div id = "show" *ngIf="flag">显示</div>
-----------------------------------------------------------
//about.component.ts
public flag:boolean = true; //定义ngIf(flag)
constructor() { }
ngOnInit() {
// 指令和组件初始化
var app:any = document.getElementById("app");
app.style.color="red"
// console.log(app)
// var show:any = document.getElementById("show"); //
// console.log(show); //第一种方法:打印为空
}
ngAfterViewInit(){
// 推荐在此生命周期中 操作Dom
var show:any = document.getElementById("show");
console.log(show); //第二种方法:打印
}
1-5 viewChild 装饰器
<div #app *ngIf="flag">显示</div>
---- /////1.给dom 命名
import { Component, OnInit, ViewChild} from '@angular/core';1. //////配置ViewChild
-----------
@Component({
selector: 'app-about',
templateUrl: './about.component.html',
styleUrls: ['./about.component.css']
})
export class AboutComponent implements OnInit {
public flag:boolean = true;
@ViewChild('app',{static:false}) app:any; //////2.
constructor() { }
ngOnInit() {
}
ngAfterViewInit(){ ///////3.
console.log(this.app);
}
}
2、指令ngFor,ngIf …
//.html
<div *ngFor="let item of arr">{{item.name}}</div>
<div *ngIf="isShow">你好</div>
//header.component.ts
export class HeaderComponent implements OnInit {
public arr:object[] = [{name:"html",age:12},{name:'css',age:23}];
public isShow:boolean=true;
// public imageUrl:string="https://dss0.baidu.com/73t1bjeh1BF3odCf/it/u=3093620924,1794231155&fm=85&s=BA917F81683046017AA9ADCC0300C023"
//public msg:string = "我喜欢写代码"
constructor() { }
...
}
3、属性绑定[src]
<img [src]="imageUrl" >
public imageUrl:string="https://dss0.baidu.com/73t1bjeh1BF3odCf/it/u=3093620924,1794231155&fm=85&s=BA917F81683046017AA9ADCC0300C023"
4、事件
4-1 (click)
<p (click)="handleClick()">{{msg}}</p>
export class HeaderComponent implements OnInit {
....
public msg:string ="我喜欢写代码"
constructor() { }
ngOnInit() {
}
handleClick(){
this.msg = "change"
}
}
4-2 (keyup)
<input type="text" (keyup)="handleEnter($event)">
handleEnter(event:any){
console.log(event.keyCode)
}
4-3 (keyup.enter)
<input type="text" #box (keyup.enter)="handleEnter(box.value)">
handleEnter(value:string){
console.log(value)
}
5、请求数据
app.module.ts配置
import {HttpClientModule} from '@angular/common/http'
imports: [
BrowserModule,
HttpClientModule
],
5-2 在发送http请求的组件中配置HttpClient,作为构造函数的参数设置
import { Component, OnInit } from '@angular/core';
import {HttpClient} from '@angular/common/http' //////
...
export class ContentComponent implements OnInit {
constructor(public http:HttpClient) { } //////
ngOnInit() {
var url:string = "http://192.168.14.15:5000/dj/program?rid=336355127"
this.http.get(url).subscribe(res=>{
console.log(res)
})
}
}
5-1 请求本地数据
import cartList from './data'
...
public cartList:any = cartList //方便数据渲染
...
constructor() {
console.log(cartList)
}
5-2 请求数据
<div *ngFor='let item of programs'>
<p>{{item.name}}</p>
<img [src]="item.coverUrl">
</div>
import {HttpClient} from '@angular/common/http'
...
export class ContainerComponent implements OnInit {
public programs:any; //放置请求到的数据
constructor(public http:HttpClient) { }
//请求数据
ngOnInit() {
var url:string = "http://192.168.14.15:5000/dj/program?rid=336355127"
this.http.get(url).subscribe(res=>{
console.log(res['programs'])
this.programs = res['programs']
})
}
6、使用api 库(antd)
导入antd(自动构造)
终端:
ng add ng-zorro-antd
yyy zh_US
<button nz-button nzType="primary">Primary</button>
二、组件
2-1 组件创建
ng g component componets/xxxxx
2-2 组件注册
@NgModule({
// 注册组件
declarations: [
AppComponent,
HeaderComponent, //注册header 组件
ContentComponent //注册content 组件
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
2-3 组件使用
//app.component.html
<app-header></app-header>
<app-content></app-content>
2-4 父子组件传值 父传子组件
.html
<p>{{title}}</p>
//子组件:Input
import { Component, OnInit ,Input} from '@angular/core';
...
@Input() title:string;
父组件:app.component.ts
<app-header [title]="title"></app-header>
export class AppComponent {
public title:string = 'hello ';
}
三、路由
angular-cli 中选中路由,之后app.component.html会多出
相当于vue中
3-1 路由
3-1-1 配置
一级路由
路由重定向
不匹配路由的处理(404)
//app-outing.module.ts中配置
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './components/home/home.component';
import { NewsComponent } from './components/news/news.component';
import { AboutComponent } from './components/about/about.component';
import { ErrorComponent } from './components/error/error.component';
const routes: Routes = [
{
path:'home',
component:HomeComponent
},{
path:'news',
component:NewsComponent
},{
path:"about",
component:AboutComponent
},{
//路由重定向
path:"",
redirectTo:"home",
pathMatch:"full"
},{
// 匹配没有设置的路由
path:"**",
component:ErrorComponent
}
];
...
export class AppRoutingModule { }
3-1-2 路由导航 ( routerLinkActive设置routerLink默认选中的路由)
<ul>
<li><a [routerLink]="['/home']" routerLinkActive="router-link-active">home</a></li>
<li><a [routerLink]="['/news']" routerLinkActive="router-link-active">news</a></li>
<li><a [routerLink]="['/about']" routerLinkActive="router-link-active">about</a></li>
</ul>
3-1-3 get传值
6-3-1 跳转:
<a [routerLink]="['/detail']" [queryParams]="{id:id}">跳转detail</a>
//id
plublic id:string="213"
--------------------
//接收传参 接收this.route.queryParams
6-3-2 接收 this.route.queryParams
//导入正在显示的路由
import {ActivatedRoute} from '@angular/router'
export class DetailComponent implements OnInit {
//构造函数中配置
constructor(public route:ActivatedRoute) { }
ngOnInit() {
//subscribe触发
this.route.queryParams.subscribe(res=>{
console.log(res)
})
}
}
3-2 动态路由
配置
跳转传值
接收参数
7-1 配置
//app-routing.module.ts
{
path:"detail/:id",
component:DetailComponent
}
7-2 跳转传值
//第一种跳转方式
<a [routerLink]="['/detail',id]" >跳转detail</a> 跳转接收queryParams
//第二种跳转方式
<a routerLink="/detail/{{id}}" >跳转detail</a>
7-3 接收参数 this.route.params
import {ActivatedRoute} from '@angular/router' //导入正在显示的路由
...
export class DetailComponent implements OnInit {
constructor(public route:ActivatedRoute) { } //构造函数的配置
ngOnInit() {
this.route.params.subscribe(res=>{ //subscribe 触发
console.log(res)
})
// this.route.queryParams.subscribe(res=>{
// console.log(res)
// })
}
}
3-3 跳转事件(this.router.navigate)
3-3-1 动态路由的事件跳转
<button (click)="handleClick()">跳转detail</button>
//导入路由
import {Router} from "@angular/router"
export class HomeComponent implements OnInit {
public id:string = "1213"
//配置
constructor(private router:Router) { }
handleClick(){
//跳转
this.router.navigate(['/detail',this.id])
}
}
3-3-2 get传值的事件跳转
<button (click)="handleClick()">跳转detail</button>
//导入NavigationExtras
import {Router,NavigationExtras} from "@angular/router"
...
//配置 NavigationExtras的参数
export class HomeComponent implements OnInit {
public id:string = "1213"
constructor(private router:Router) { }
handleClick(){
let navigationExtras:NavigationExtras ={
queryParams:{
"id":this.id
}
}
//跳转
this.router.navigate(['/detail'],navigationExtras)
}
}
3-4 子路由
{
path:'news',
component:NewsComponent,
children:[
{
path:"morning",
component:MorningComponent
},{
path:"night",
component:NightComponent
},{
path:"",
redirectTo:"morning",
pathMatch:"full"
}
]
}
//在父路由对应的组件中的html中
<router-outlet></router-outlet>
四、service
1-1 生成服务
ng g //检查组件
ng g service services/common
1-2 在跟模块中配置
app.module.ts
import { AboutComponent } from './components/about/about.component';
import { CommonService} from './services/common.service'; ////////
@NgModule({
declarations: [
AppComponent,
HomeComponent,
AboutComponent
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [CommonService], ///////
bootstrap: [AppComponent]
})
export class AppModule { }
1-3 组件使用服务
//home.component.ts
//使用:
import { Component, OnInit } from '@angular/core';
import { CommonService } from '../../services/common.service' //////1.导入服务
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
constructor(public common:CommonService) { } //////2.构造函数中配置
ngOnInit() {
console.log(this.common.defaultCity) //////3.使用
}
}
//home.component.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class CommonService {
public defaultCity:string = "武汉" /////
constructor() { }
}
1-4 城市例子:
点击获取数据 改变数据 缓存数据
<p>home works!</p>
<p>{{city}}</p>
<h2>热门城市</h2>
<button *ngFor = "let item of hotCities" class="btn" //////
(click) = "handleClick(item)"> |
{{item}} |
</button> //////
//home.component.spec.ts
export class HomeComponent implements OnInit {
public city:any;
public hotCities:string [] = ["北京","上海","深圳","广州"] ///////
constructor(public common:CommonService) { }
ngOnInit() {
this.city = this.common.defaultCity
}
handleClick(item:string){ //////
console.log(item)
}
}
改变数据
//common.service.ts
public defaultCity:string = "武汉"
缓存数据
home
export class HomeComponent implements OnInit {
public city:any;
public hotCities:string [] = ["北京","上海","深圳","广州"]
constructor(public common:CommonService) { }
ngOnInit() {
// this.city = this.common.defaultCity
this.city = this.common.getCity(); //获取缓存
}
--------------1.-----|
handleClick(item:string){
console.log(item)
this.common.changeCity(item); //改变缓存
}
----------------2.-----|
ngDoCheck(){
console.log(1)
this.city = this.common.getCity(); //改变缓存
}
//serve
export class CommonService {
public defaultCity:string = "武汉"
constructor() { }
getCity(){ //如果有缓存 获取缓存
if(localStorage.getItem("city")){
// 获取缓存
this.defaultCity = localStorage.getItem("city")
}
return this.defaultCity;
}
changeCity(value:string){ //点击设置缓存
this.defaultCity = value;
// 设置缓存
localStorage.setItem("city",value);
}
五、路由模块
5-1 配置一个路由模块
ng g module views/home --routing
ng g component views/home //配置主组件
5-2 配置模块中的路由
//home-routing.module.ts
import { HomeComponent } from './home.component';
const routes: Routes = [
{
path:"",
component:HomeComponent
}
]
5-3 配置主路由
const routes: Routes = [
{
path:"home",
loadChildren:()=>import('./views/home/home.module').then(m=>m.HomeModule)
}
];