Angular_学习笔记

Angular

此笔记根据b站IT营视频学习所做的笔记,使用的是 angular 11.2.3,视频链接如下 b站学习视频

1.环境配置

shell 复制代码
# 更换镜像源
npm config set registry https://registry.npmmirror.com
# 查看是否成功 
npm config get registry
# 切换node源
nvm use 12.22.12
# 验证node版本
node -v
npm -v
# 安装脚手架
npm install -g  @angular/cli
npm install -g @angular/cli@11.2.3
# 查看ng版本
ng version

2.创建项目

shell 复制代码
ng new angulardemo01
ng new angulardemo01 --skip-install
cd angulardemo01
npm install
ng serve --open
2.1 app.module
js 复制代码
/* 这个文件是Angular根模块,告诉Angular如何组装应用 */

// 浏览器解析模块 
import { BrowserModule } from '@angular/platform-browser';
// Angular 核心模块
import { NgModule } from '@angular/core';
// 根组件
import { AppComponent } from './app.component';

/* NgModule装饰器,接受一个元数据对象,告诉 Angular 如何编译和启动应用 */
@NgModule({
  declarations: [ /** 配置当前项目运行的组件 */
    AppComponent
  ],
  imports: [ /** 配置当前模块运行依赖的其它模块 */
    BrowserModule
  ],
  providers: [], /** 配置项目所需要的服务 */
  bootstrap: [AppComponent] /** 指应用的主视图(称为根组件)通过引导根AppModule来启动应用 */
})
// 暴露出去的模块,此处为根模块,不需要给其他人暴露
export class AppModule { }
2.2 app.component.ts
js 复制代码
// 引入核心模块的 Component
import { Component } from '@angular/core';

@Component({
  selector: 'app-root', // 使用这个组件的名称
  templateUrl: './app.component.html', // html
  styleUrls: ['./app.component.scss'] //css
})
export class AppComponent {
  title = 'angulardemo01'; // 定义属性
   
  constructor(){ //构造函数

  }
}
2.3 新建组件
js 复制代码
ng g component components/new

组件new

ng g component components/home

3. 属性

js 复制代码
  public title = '新闻title';

  msg = '我是一个新闻组件的msg';

  username:String = '用户名';

  public student:any = 123;
  
  public userinfo:any={
      username:'张三',
      age:'20'
  }
  // 推荐
  public studentText:any = '我是一个学生的简介属性';
  // 推荐
  public list:any=['第一个新闻',22222,'我是第三个新闻']
  public message:any;
  public items:Array<number> = [123,234,546]
  
   public cars:any = [
    {
      cate:'宝马',
      list:[{
        title:'宝马x1',
        price:'10万'
      },
      {
        title:'宝马x2',
        price:'20万'
      },
      {
        title:'宝马x3',
        price:'30万'
      }]
    },
    {
      cate:'奥迪',
      list:[{
        title:'奥迪q1',
        price:'40万'
      },
      {
        title:'奥迪q2',
        price:'50万'
      },
      {
        title:'奥迪q3',
        price:'60万'
      }]
    }
  ]
  
  constructor() {
    this.message = '这是给属性赋值--改变属性的值'

    console.log(this.message);

    this.msg = '我是改变属性后的值 '
   }

4. 数据绑定

js 复制代码
<div [title]="student">
     张三
</div>

<span [innerHtml] = 'content' class="red"></span>

<ul>
    <li *ngFor="let item of items">
        {{item}}
    </li>
</ul>

<ul>
    <li *ngFor="let item of userlist">
        {{item.username}} --- {{item.age}} 
    </li>
</ul>

<ul>
    <li *ngFor="let item of cars">
        <h2>{{item.cate}}</h2>
        <ol>
            <li *ngFor="let car of item.list">
                {{car.title}} ---  {{car.price}}
            </li>
        </ol>
    </li>
</ul>

5.条件判断语句

ngStyle ngClass
js 复制代码
<ul>
    <li *ngFor="let item of list;let key=index;">
      <span *ngIf="key == 1" class="red"> {{key}}  --- {{item.title}} </span>
      <span *ngIf="key != 1"> {{key}}  --- {{item.title}} </span>
    </li>
</ul>

<h1>条件判断语句 ngif</h1>

<div *ngIf="!flag">
    <img src="assets/images/pic1.png" alt="随便写的" />
</div>
<div *ngIf="flag">
    <img  [src]="picURL" />
</div>


<div [ngSwitch]="orderStatus">
    <div *ngSwitchCase="1">已支付</div>
    <div *ngSwitchCase="2">支付并确认</div>
    <div *ngSwitchCase="3">已发货</div>
    <div *ngSwitchCase="4">已收获</div>
    <div *ngSwitchCase="5">无效订单</div>
    <div *ngSwitchDefault>output2</div>
</div>

<ul>
    <li *ngFor="let item of list;let key = index;">
        <span *ngIf="key==1" [ngClass]="{'red': key==1}">{{key}} ---- {{item.title}}</span>
        <span *ngIf="key==2"  [ngClass]="{'orange': key==2}">{{key}} ---- {{item.title}}</span>
    </li>
</ul>

<p style="color: red">我是一个p标签</p>

<p [ngStyle]="{color: 'red'}">我是一个p标签</p>

<p [ngStyle]="{color: attr}">我是一个p标签</p>

6.管道

js 复制代码
<h2>管道</h2>

{{today | date:'yyyy-MM-dd HH:mm:ss'}}

<button (click)="run()">执行事件</button>
<hr/>
<button (click)="getData()">执行方法获取数据</button>
<hr/>
<span>{{title}}</span>
<button (click)="setData()">执行方法设置数据</button>

<h1>表单事件 事件对象</h1>

keydown:<input type="text" (keydown)="keydown($event)">
keyup:<input type="text" (keyup)="keyUp($event)">
runEvent

<button (click)="runEvent($event)">执行方法获取事件对象</button>

7.表单对象、事件对象

js 复制代码
app.moudle.ts
import { FormsModule } from '@angular/forms'
  imports: [
    FormsModule
  ],

<input type="text" [(ngModel)]="keywords">
{{keywords}}

<button (click) = "changeKeywords()" >改变keywords</button>

<button (click) = "getKeywords()" >获取keywords</button>

8.数据持久化

js 复制代码
ng g service services/storage

# app.module.ts
import { StorageService } from './services/storage.service'
providers: [StorageService],

# 其它组件引用不推荐()
import { StorageService } from '../../services/storage.service';
// 不推荐
var storage = new StorageService();

# 推荐
import { StorageService } from '../../services/storage.service';
constructor(public storeage:StorageService) {
	this.storeage.get();
}


  set(key:string,value:any){
    localStorage.setItem(key,JSON.stringify(value))
  }
  get(key:string){
    var item:any = localStorage.getItem(key)
    if(item){
      return JSON.parse(item);
    }
    return null;
  }

  remove(key:string){
    localStorage.removeItem(key);
  }

9.原生操作dom

js 复制代码
  // 视图加载完成后执行的方法,建议把dom操作放在这里
  ngAfterViewInit():void{
    let box1:any= document.getElementById('box1');
    // console.log(box2.innerHTML)
    box1.style.color = 'blue'
  }

10.viewchild-父组件调用子父组件属性

js 复制代码
# html
<div #mybox>
    我是一个div
</div>

  @ViewChild('mybox') mybox:any;
  constructor() { }

# typescript
ngAfterViewInit(){
    console.log(this.mybox.nativeElement.innerHTML)
    this.mybox.nativeElement.style.width = '100px';
    this.mybox.nativeElement.style.height = '100px';
    this.mybox.nativeElement.style.background = 'red'
  }

11.viewchild 父组件调用子组件的方法

js 复制代码
# html
<app-header #header></app-header>
<p>news works!</p>

<div #mybox>
    我是一个div
</div>

<button (click) = 'clickMethod()'>点击</button>


# typescript
  @ViewChild('mybox') mybox:any;
  @ViewChild('header') header:any
  constructor() { }
  
  clickMethod(){
    this.header.run();
  }

12. css3 动画

js 复制代码
# html
<div class="content">
    内容区域
    <button (click)="showAside()">显示侧边栏</button>
    <button (click)="hiddenAside()">隐藏侧边栏</button>
</div>


<aside id='aside'>
    这是一个侧边栏
</aside>

# css
#aside{
    width: 200px;
    height: 100%;
    position: absolute;
    right: 0px;
    top: 0px;
    background: #000;
    color: #fff;
    transform: translate(100%,0);
    transition: all 2s;
}

# typescript
  showAside(){
    var asideDom:any =  document.getElementById('aside');
    asideDom.style.transform = "translate(0,0)";
  }

  hiddenAside(){
    var asideDom:any =  document.getElementById('aside');
    asideDom.style.transform = "translate(100%,0)";
  }

13.父子组件的通信-属性

js 复制代码
# 父1 typescripe
 public title:string = '我是一个首页标题-news'
# 父1 html
<app-header #header [title]="title"></app-header>

# 父2 typescripe
 public title:string = '我是一个首页标题-home'
# 父2 html
<app-header #header [title]="title"></app-header>

# 子组件
<h1 style="background: red;">{{title}}</h1>
@Input() title:any;

14.父子组件的通信-方法

js 复制代码
# 父1 typescripe
  run(){
    alert('我是news的run方法')
  }
# 父1 html
<app-header [title]="title" [run]="run"></app-header>

# 父2 typescripe
  run(){
    alert('我是home的run方法')
  }
# 父2 html
<app-header [title]="title" [run]="run"></app-header>


# 子 typescript
  @Input() run:any;
  
  gerParentRun(){
      this.run();
  }
# 子 html
 
  <button (click) = "gerParentRun()">子组件执行父组件的run()</button>
  
# 传递父组件
<app-header [home]="this"></app-header>

15.@Output 子组件给父组件广播,调用父组件方法

js 复制代码
# 父组件 html
<app-footer (outer)="runOuter($event)"></app-footer>
# 父组件 ts
  runOuter(e:any){
    alert('我是home组件的runOuter方法')
    console.log(e)
  }
# 子组件 html
<button (click)="sendParent()">通过@Output给父组件广播</button>
# 子组件 ts
  sendParent(){
    this.outer.emit("我是子组件的数据")
  }

16.生命周期函数(勾子方法)

阶段 方法 摘要
创建 constructor 标准 JavaScript 类构造函数。当 Angular 实例化组件时运行。
变更检测 ngOnInit 在 Angular 初始化完组件的所有输入之后运行一次。
ngOnChanges 每次组件的输入发生更改时都会运行。
ngDoCheck 每次检查此组件是否有更改时都会运行。
ngAfterContentInit 在组件的内容初始化之后运行一次。
ngAfterContentChecked 每次检查此组件内容是否有更改时都会运行。
ngAfterViewInit 在组件的视图初始化之后运行一次。
ngAfterViewChecked 每次检查组件的视图是否有更改时都会运行。
渲染 afterNextRender 所有组件下次渲染到 DOM 后运行一次。
afterEveryRender 每次所有组件渲染到 DOM 后都会运行。
销毁 ngOnDestroy 在组件销毁之前运行一次。

实例

js 复制代码
  constructor() { 
    console.log('constructor')
  }

  ngOnInit(): void {
    console.log('ngOnInit')
  }

   ngOnChanges(): void {
    console.log('ngOnChanges 父子组件传值触发')
  }


  ngDoCheck(){
    console.log('03ngDoCheck --- 检测,并在发生angular 无法或者不愿意自己检测的变化时作出的反应')
  }

  ngAfterContentInit(){
    console.log('04ngAfterContentInit ---- 当把内容投影进组件之后调用')
  }

  ngAfterContentChecked(){
      console.log('05ngAfterContentChecked --- 每次完成被投影组件内容的变更检测之后调用')
  }


  ngAfterViewInit(){
    console.log('06ngAfterViewInit --- 初始化组件视图及子视图之后调用(dom操作在这里面)')
  }

  ngAfterViewChecked(){
    console.log('07ngAfterViewChecked --- 每次做完组件视图和子视图的变更检测之后调用')
  }

  afterNextRender(){
    console.log('afterNextRender')
  }

  
  afterEveryRender(){
    console.log('afterEveryRender')
  }

   ngOnDestroy(){
    console.log('08ngOnDestroy')
  }

17.常见的异步编程的几种方法。

17.1.回调函数
js 复制代码
// 异步回调定义
  getCallbackData(cb:any){
    setTimeout(() => {
      var username = '张三';
      cb(username)
    }, 1000);
  }

// 使用异步回调
  ngOnInit(): void {

    let data = this.request.getCallbackData((data:any) =>{
        console.log(data)
    });
    console.log(data)

  }
17.2.promise
js 复制代码
	//  定义promise
	getPromiseData(){
        return new Promise((resolve,reject)=>{
          setTimeout(() => {
            var username = '张三';
            resolve(username)
          }, 1000);
    })

    // 使用promise
    var promiseData = this.request.getPromiseData();
    promiseData.then((data)=>{
      console.log('promiseData-',data)
    })
17.3 rxjs
js 复制代码
// rxjs定义
   getrxjsData(){
    return new Observable((observer)=>{

      setTimeout(() => {
        var username = '李四';
        observer.next(username);
        // observer.error('失败')
      }, 2000);
    })
   }
   
// rxjs 获取异步数据
    var observerData = this.request.getrxjsData();
    observerData.subscribe((data)=>{
      console.log('rxjs-observerdata',data)
    })
17.4 rxjs 撤回
js 复制代码
    // 过一秒后撤回rxjs的操作
    var streem = this.request.getrxjsData();
    var d = streem.subscribe((data)=>{
      console.log('rxjs-observerdata',data)
    })

    setTimeout(() => {
      d.unsubscribe(); // 取消订阅
    }, 1000);
17.5 rxjs 多次执行
js 复制代码
   // rxjs  多次执行
   getrxjsIntervalData(){
      return new Observable((observer) => {
        var count = 0;
        setInterval(()=>{
           count ++;
           var username = '王五' + count
           observer.next(username)
        }, 1000)
      })
   }

	// 多次执行
    var rxjsInterval = this.request.getrxjsIntervalData();
    rxjsInterval.subscribe(data =>{
      console.log(data)
    })
17.6 map,filter
js 复制代码
import {map,filter} from 'rxjs/operators'

用工具方法对返回的数据做处理

// 方法定义
   getRxjsIntervalNum(){
    return new  Observable(observer=>{
      var count = 0;
      setInterval(()=>{
        count++;
        observer.next(count)
      },2000)
    })
   }
   
// 管道
    var rxjsNum = this.request.getRxjsIntervalNum();
    rxjsNum.pipe(
      filter((value:any) :any =>{
        if(value % 2 == 0){
          return true;
        }
      })
    ).subscribe(data =>{
      console.log(data)
    })

// map

    var rxjsNum = this.request.getRxjsIntervalNum();
    rxjsNum.pipe(
      map((value:any) :any =>{
        return value*value;
      })
    ).subscribe(data =>{
      console.log(data)
    })
    
// filter + map
    var rxjsNum = this.request.getRxjsIntervalNum();
    rxjsNum.pipe(
      filter((value:any) :any =>{
        if(value % 2 == 0){
          return true;
        }
      }),
      map((data:any):any =>{
        return  data*data;
      })
    ).subscribe(data =>{
      console.log(data)
    })

    console.log('ngOnInit')
  }

18. angular 中的数据交互(get jsonp post)

18.1 get
js 复制代码
# app.moudle
import {HttpClientModule} from '@angular/common/http'

# 具体的模块
import {HttpClient} from '@angular/common/http'

  executeGet(){
    let api = 'http://a.itying.com/api/productlist';
    this.http.get(api).subscribe((data:any) =>{
        console.log(data)
    })
  }
18.2 post
js 复制代码
# app.moudle
import {HttpClientModule} from '@angular/common/http'

# 具体的模块
import {HttpClient,HttpHeaders} from '@angular/common/http'

 // 存在跨域问题
  doLogin(){

    const httpOptions = {headers: new HttpHeaders({'Content-Type':'application/json'})}
    let jsonObj = {
      'username': '张三',
      'age':20
    }
    let api = 'http://127.0.0.1:3000/dologin'
    this.http.post(api,jsonObj,httpOptions).subscribe((response)=>{
      console.log(response)
    })
  }
18.3 jsonp
js 复制代码
# app.moudle
import {HttpClientModule,HttpClientJsonpModule} from '@angular/common/http'

# 具体的模块
import {HttpClient,HttpHeaders} from '@angular/common/http'
  constructor(public http:HttpClient) { }
  
  // 支持跨域
  getJsonpData(){
    let api = 'http://a.itying.com/api/productlist';
    /**
     * 验证是否支持jsonp格式 http://a.itying.com/api/productlist?callback=aaaa
     * http://a.itying.com/api/productlist?cb=aaaa
     *  */ 
    this.http.jsonp(api,'callback').subscribe(response =>{
      console.log(response)
    })
  }  
18.4 axios
js 复制代码
npm install axios --save

# app.moudle
import { HttpserviceService } from 'src/app/services/httpservice.service';
providers: [StorageService,RequestService,HttpserviceService],

# 具体的模块
import { HttpserviceService } from '../../services/httpservice.service'

  constructor(
    public http:HttpClient,
    public httpservice:HttpserviceService

  ) { }

19 路由跳转

19.1 普通路由跳转
js 复制代码
# app.route.moule.ts
import { NewsComponent } from './components/news/news.component';
import { HeadersComponent } from './components/headers/headers.component';
import { HomeComponent } from './components/home/home.component';
import { TaskComponent } from './components/task/task.component';


const routes: Routes = [
  
  {
    path:'home', component:HomeComponent
  },{
    path:'task', component:TaskComponent
  },{
     path:'news',component:NewsComponent
  },{
    path:'header',component:HeadersComponent
  },// 匹配不到路由情况西按默认跳转到home,记住要放在最后
  {
    path:'**',
    redirectTo:'home'
  },
  
];

# app.html
<h1>我是根组件</h1>

<header class="header">

    <a [routerLink]="['/task']" routerLinkActive="router-link-active" ]>任务</a>
    <a [routerLink]="['/header']" routerLinkActive="router-link-active" >头部</a>
    <a [routerLink]="['/home']" routerLinkActive="router-link-active" >主页</a>
    <a [routerLink]="['/news']" routerLinkActive="router-link-active" >新闻页</a>


</header>


<router-outlet></router-outlet>
19.2 路由链接传参数
js 复制代码
// 新闻页
<ul>
    <li>
        <a [routerLink]="['/content']" [queryParams]="{aid:1}" >链接1</a>
    </li>
    <li>
        <a [routerLink]="['/content']" [queryParams]="{aid:2}" >链接2</a>
    </li>
</ul>

// 新闻详情页
import { ActivatedRoute } from '@angular/router'

  constructor(
    public  route : ActivatedRoute
  ) { }

  ngOnInit(): void {
    console.log(this.route.queryParams)
    this.route.queryParams.subscribe((data:any)=>{
      console.log(data)
    })
  }
19.3 动态路由
js 复制代码
# app.route.moudle.ts
{
    path:'detail/:aid',component:DetailComponent
  }
  
# html
<ul>
    <li>
        <a [routerLink]="['/detail' , 1]"  >详情1</a>
    </li>
    <li>
        <a [routerLink]="['/detail' , 2]" >详情2</a>
    </li>
</ul>

# detail.ts
import { ActivatedRoute } from '@angular/router'

  constructor(
    public route:ActivatedRoute
  ) { }
  
  ngOnInit(): void {
    this.route.params.subscribe((data:any) =>{
          console.log(data)
    })
  }
19.4 动态路由的js跳转
js 复制代码
# ts
import { Router } from '@angular/router';

  constructor(public router:Router) { }
  
  goProductContent(){
    // 路由跳转 普通路由
    this.router.navigate(['/productcontent']);
  }

  goDetail(){
 	 // 动态路由
    this.router.navigate(['/detail',9]);
  }
# html
<button (click)="goProductContent()">前往产品详情页</button>
19.5 路由get传值js跳转
js 复制代码
  goContent(){
    let queryParams:NavigationExtras = {
      queryParams:{
        'aid':99
      }
    }

    this.router.navigate(['/content'],queryParams);
  }

20 父子路由、嵌套路由、默认跳转子路由

js 复制代码
# route.moudle.ts
{
    path:'home', component:HomeComponent,
    children:[
      {
        path:'sysconfig',component:SysmanageComponent
      },{
         path:'taskmange',component:TaskmanageComponent
      },{
        path:'**',
        redirectTo:'sysconfig'
      }]
  },{
    path:'task', component:TaskComponent,
    children:[
      {
        path:'systask',component:SystaskComponent
      },{
        path:'cvstask',component:CvstaskComponent
      },{
        path:'**',
        redirectTo:'systask'
      }
    ]
  }

# html
<div class="content">
    <div class="left">
        <a [routerLink]="['/home/sysconfig']" routerLinkActive="router-link-active" >系统配置</a>
        
         <br>
        <a [routerLink]="['/home/taskmange']" routerLinkActive="router-link-active" >任务管理</a>
         <br>
    </div>
    <div class="right">
        <router-outlet></router-outlet>
    </div>
</div>

# html-2
<div class="content">
    <div class="left">
        <a [routerLink]="['/task/systask']" routerLinkActive="router-link-active" >主机漏扫任务</a>
        <br>
        <a [routerLink]="['/task/cvstask']" routerLinkActive="router-link-active" >网站检测任务</a>
        <br>
    </div>
    <div class="right">
        <router-outlet></router-outlet>
    </div>
</div>
相关推荐
楼田莉子2 小时前
设计模式:设计模式的相关概念与原则
c++·学习·设计模式
sheeta19982 小时前
LeetCode 每日一题笔记 日期:2025.04.06 题目:874. 模拟行走机器人
笔记·leetcode·机器人
峥嵘life2 小时前
Android 无线投屏相关知识介绍
android·学习
oi..2 小时前
Linux入门(2)
linux·笔记·测试工具·安全·网络安全
那我懂你的意思啦2 小时前
微服务学习+商城
学习·微服务·架构
AI_零食2 小时前
Flutter 框架跨平台鸿蒙开发 - 鸿蒙版本跳棋游戏应用
学习·flutter·游戏·华为·交互·harmonyos
yangyanping201082 小时前
Go语言学习之Go Gin 生产级 flag 启动命令模板
开发语言·学习·golang
知识分享小能手2 小时前
MongoDB入门学习教程,从入门到精通,MongoDB的分片简介(14)
数据库·学习·mongodb
Lucis__2 小时前
Linux系统收官篇:线程学习的一些心得总结
linux·学习·线程