Angular基础学习(入门 --> 入坑)

目录

[一、Angular 环境搭建](#一、Angular 环境搭建)

二、创建Angular新项目

三、数据绑定

四、ngFor循环、ngIf、ngSwitch、[ngClass]、[ngStyle]、管道、事件、双向数据绑定--MVVM

[五、DOM 操作 (ViewChild)](#五、DOM 操作 (ViewChild))

六、组件通讯

七、生命周期

[八、Rxjs 异步数据流](#八、Rxjs 异步数据流)

[九、Http 请求](#九、Http 请求)

[十、使用axios 请求数据](#十、使用axios 请求数据)

十一、路由

[十二、动态路由 & get 传值](#十二、动态路由 & get 传值)

[十三、动态路由的 js 跳转路由](#十三、动态路由的 js 跳转路由)

十四、父子路由(嵌套路由)

十五、vdemo项目


一、Angular 环境搭建

1、安装nodejs,通过node -v查看node版本安装是否成功(自行百度安装)

2、安装npm / yarn / cnpm /pnpm,npm -v查看npm版本是否成功(自行百度安装)

3、npm install -g @angular/cli@7.0.6(学习的版本稳定)

4、ng v 验证安装是否成功

二、创建Angular新项目

1、使用命令创建

ng new vdemo

2、配置选项(1、是否使用路由 【暂时不用N】,2、会哪个选那个,上下选择,回车就会创建好项目,并且下载好依赖)

npm new vdemo --skip-install -- 创建项目不下载依赖 -- 后面 自行执行 npm i

也可以自行到目录下执行npm i 下载依赖

3、项目启动

ng serve --open

4、angular6 中使用socket.io报global is not defined 错误如何解决

angular6 中使用socket.io报global is not defined 错误如何解决

5、目录介绍

6、自定义组件命令

https://angular.dev/cli

ng g 查看模块

ng g component components/news 创建组件

在根组件引入news组件

效果:

三、数据绑定

<----! html ------->

html 复制代码
<h1>angular模板里面绑定数据</h1>
<p>
  {{ title }}
</p>

<p>{{ msg }}</p>

<p>{{ username }}</p>
<p>{{ student }}</p>
<p>{{ userInfo.username }}、{{ userInfo.age }}</p>
<p>{{ message }}</p>

<hr />
<!-- ----------------------------------------------------------------- -->

<h1>angular模板里面绑定属性</h1>
<div title="我是一个属性">宇哥很帅</div>

<br />

<div [title]="student">宇哥很帅-lalal</div>

<hr />

<!-- ----------------------------------------------------------------- -->
<h1>angular模板里面绑定html</h1>

<div>{{ content }}</div>
<!-- 解析html -->
<div [innerHTML]="content" class="red"></div>
<hr>
<!-- ----------------------------------------------------------------- -->

<h1>angular模板里面允许做简单的运算</h1>
1+2={{ 1 + 2 }}
<hr>
<!-- ----------------------------------------------------------------- -->
<h1>angular模板里面数据循环</h1>
<br />

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

<br />

<ul>
  <li *ngFor="let item2 of list">{{ item2 }}</li>
</ul>
<br />

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

<br />
<ul>
  <li *ngFor="let item4 of listList">{{ item4.name }}、{{ item4.age }}</li>
</ul>

<br />
<ul>
  <li *ngFor="let item5 of cars">
    <h2>{{ item5.name }}</h2>
    <ol>
      <li *ngFor="let its of item5.list">{{ its.name }} --- {{ its.price }}</li>
    </ol>
  </li>
</ul>

<----! ts ------->

javascript 复制代码
import { Component, OnInit } from "@angular/core";

@Component({
  selector: "app-news",
  templateUrl: "./news.component.html",
  styleUrls: ["./news.component.css"],
})
export class NewsComponent implements OnInit {
  // 声明属性的几种方法
  // public  共有(默认) 可以在这个类里面使用、也可以在类外面使用
  // protected  保护类型  它只有在当前类和它的子类里面访问
  // private   私有   当前类才可以访问这个属性只有在
  
  public title = "我是新闻组件";

  msg = "我是新闻组件中的msg";

  private username = "张三";

  // 推荐
  public student: any = "我是一个学生";

  public userInfo: object = {
    username: "张三",
    age: "20",
  };

  public message: any;

  public content="<h2>我是新闻组件中的content</h2>";

  // 定义数组
  public arr=['111','222','333']
  // 推荐
  public list:any[] = ['我是第一个',222222,'443425']
  public items:Array<string>=['第一个新闻','第二个新闻']
  
  // 复杂数组
  public listList:any[]=[
    {
      id:1,
      name:'张三',
      age:20
    },
    {
      id:2,
      name:'李四',
      age:22
    },
    {
      id:3,
      name:'王五',
      age:23
    }
  ]

  public cars:any[]=[
    {
      name:'宝马',
      list:[
        {
          name:'宝马X1',
          price:'30W'
        },
        {
          name:'宝马X2',
          price:'20W'
        }
      ]
      
    },
    {
      name:'奥迪',
      list:[
        {
          name:'奥迪Q1',
          price:'130W'
        },
        {
          name:'奥迪Q2',
          price:'1120W'
        }
      ]
      
    }
  ]

  constructor() {
    this.message = "这是给属性赋值--(改变属性的值)";

    this.msg = "我是新闻组件中的msg==(我是改变后的值)";
  }

  ngOnInit() {}
}

效果:

四、*ngFor循环、*ngIf、ngSwitch、[ngClass]、[ngStyle]、管道、事件、双向数据绑定--MVVM

<----! html ------->

html 复制代码
<h1>引入图片</h1>

<img style="width: 300px; height: 300px" src="assets/images/1.jpg" alt="" />
<hr />

<img style="width: 300px; height: 300px" [src]="picUrl" alt="" />
<hr />

<h1>循环数据 显示数据的索引(key)</h1>
<ul>
  <li *ngFor="let item of list; let key = index">
    {{ key }}--{{ item.title }}
  </li>
</ul>

<hr />

<h1>条件判断语句 *ngIf</h1>
<div *ngIf="flag">
  <img style="width: 300px; height: 300px" src="assets/images/1.jpg" alt="" />
</div>
<div *ngIf="!flag">
  <img style="width: 300px; height: 300px" [src]="picUrl" alt="" />
</div>

<hr>
<ul>
  <li *ngFor="let item of list; let key = index">
    <span *ngIf="key == 1" class="reds">{{ key }}--{{ item.title }}</span>
    <span *ngIf="key != 1">{{ key }}--{{ item.title }}</span>
  </li>
</ul>
<hr>

<h1>条件判断语句 *ngSwitch</h1>
<ul [ngSwitch]="orderStatus">
  <li *ngSwitchCase="1">下单</li>
  <li *ngSwitchCase="2">支付</li>
  <li *ngSwitchCase="3">已支付</li>
  <li *ngSwitchCase="4">已购买</li>
</ul>
<hr>

<h1>属性 [ngClass]、[ngStyle]</h1>
<div class="reds">
  ngClass1111
</div>
<hr>
<div [ngClass]="{'reds': 'true', 'blue': 'false'}">
  ngClass1111
</div>
<hr>
<div [ngClass]="{'orange': 'flag', 'blue': '!flag'}">
  ngClass1111
</div>
<hr>


<h1>循环数组、改变数组某一项的样式</h1>
<ul>
  <li *ngFor="let item of list; let key = index" [ngClass]="{'reds': key == 1, 'blue':key == 2,'orange':key == 3}">
    {{ key }}--{{ item.title }}
  </li>
</ul>
<hr>

<p style="color: aqua;">我是一个p标签</p>
<br>
<p [ngStyle]="{'color':'pink'}">我是一个p标签</p>
<br>
<p [ngStyle]="{'color':attr}">我是一个p标签</p>
<hr>


<h1>管道</h1>
<p> {{ today | date:'yyyy-MM-dd HH:mm ss' }}</p>
<hr>

<h1>事件</h1>
<p>{{title}}</p>
<br>
<button (click)="run()">点击我</button>
<br>
<button (click)="getData()">点击我获取title</button>
<br>
<button (click)="changeData()">点击我改变title</button>
<br>
<button (click)="runEvent($event)">点击我改变颜色</button>
<hr>

<h1>表单事件、事件对象</h1>
keyDown:
<input type="text" (keydown)="keyDown($event)" />
<br>
keyUp:
<input type="text" (keydown)="keyUp($event)" />
<hr>

<h1>双向数据绑定--MVVM</h1>
<input type="text" [(ngModel)]="keywords" />
<p>{{keywords}}</p>
<br>
<button (click)="changeKeywords()">改变keyWords值</button>
<br>
<button (click)="getKeywords()">获取keyWords值</button>

<----! ts ------->

javascript 复制代码
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
  public title = '我是标题'

  public keywords = '我是默认值'
  
  public picUrl = 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png'
  
  public list:any[] = [
    {
      title: 'title1',
    },
    {
      title: 'title2',
    },
    {
      title: 'title3',
    },
    {
      title: 'title4',
    }
   ]

   public flag:boolean = false;

   public orderStatus:number=1
   
   public attr:string = 'orange'

   public today:Date = new Date()

  constructor() { }

  ngOnInit() {
  }
  run(){
    alert('点击了我-哈哈')
  }
  getData(){
    alert(this.title)
  }

  changeData(){
    this.title = '我是改变后的title'
  }
  runEvent(e){
    let dom:any = e.target
    dom.style.color = 'red'
  }

  // 表单事件
  keyDown(e){
    if(e.keyCode == 13){
      alert('按下回车')
    }else{
      console.log(e.target.value)
    }
  }

  keyUp(e){
    if(e.keyCode == 13){
      console.log(e.target.value)
      alert('keyUp按下回车')
    }
  }
  // 双向数据绑定
  changeKeywords(){
    this.keywords = '我是改变后的值'
  }
  getKeywords(){
    alert(this.keywords)
  }

}

效果:

五、DOM 操作 (ViewChild)

<----! html ------->

html 复制代码
<app-header #header></app-header>

<hr>

<div #myBox>
  xinwen
</div>
<button (click)="getChild()">获取header子组件值</button>

<----! ts ------->

javascript 复制代码
import { Component, OnInit,ViewChild } from '@angular/core';

@Component({
  selector: 'app-news',
  templateUrl: './news.component.html',
  styleUrls: ['./news.component.css']
})
export class NewsComponent implements OnInit {
  
  @ViewChild('myBox') myBox:any
  @ViewChild('header') header:any

  constructor() { }

  ngOnInit() {
  }
  ngAfterViewInit(){
    this.myBox.nativeElement.style.color = 'blue'
  }
  getChild(){
    this.header.run()
  }

}
javascript 复制代码
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }
  run(){
    alert('我是header子组件!!!')
  }

}

原生 js 获取DOM

<----! html ------->

html 复制代码
<h1>DOM 操作</h1>

<div id="box">
  this is box
</div>

<div id="box1" *ngIf="flag">
  this is box1111111
</div>

<----! ts ------->

javascript 复制代码
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
  public flag:boolean = true

  constructor() { }

  ngOnInit() {
    let box = document.getElementById("box")
    box.style.color = 'red'

    /*
      使用ngif 获取不到DOM 节点
      let box1 = document.getElementById("box1")
      box1.style.color = 'yellow'
    */ 

    
  };
  // 视图加载完成,获取DOM 节点
  ngAfterViewInit(){
    let box1 = document.getElementById("box1")
    box1.style.color = 'pink'
  }

}

父传子 / 获取一个组件的实例 (ViewChild)

效果图:

六、组件通讯

1、父传子 @input

获取父组件的方法

把整个父组件传给子组件 使用 this

父组件通过@ViewChild主动获取子组件的数据和方法

2、子传父 @Output 、EventEmiter

3、非父子组件的通信(eg:兄弟) todolist里有

3.1、lacalstorage

3.2、service 服务

3.3、Angular文档:https://www.angular.cn/guide/lifecycle-hooks

七、生命周期

<----! lifecycle.component.html ------->

html 复制代码
<h1>{{msg}}</h1>
<hr>
<br>
<button (click)="changeMsg()">改变Msg</button>
<br>
<br>
<input type="text" [(ngModel)]="userinfo">

<----! lifecycle.component.ts ------->

javascript 复制代码
import { Component, OnInit ,Input} from "@angular/core";

@Component({
  selector: "app-lifecycle",
  templateUrl: "./lifecycle.component.html",
  styleUrls: ["./lifecycle.component.css"],
})
export class LifecycleComponent implements OnInit {

  @Input('title2') title2:string;
  

  public msg: string = "我是一个生命周期演示哦";

  public userinfo: string = "";
  public oldUserinfo: string = "";
  constructor() {
    console.log(
      "00构造函数执行了---除了使用简单的值对局部变量进行初始化之外,什么都不应该做"
    );
  }
  ngOnChanges() {
    console.log(
      "01ngOnChanges执行了---当绑定的输入属性的值发生变化时调用 (父子组件传值会触发)"
    );
  }

  ngOnInit() {
    console.log("02ngonInit执行了--- 请求数据一般放在这个里面");
  }
  ngDoCheck() {
    // 写一写自定义操作
    console.log(
      "03ngDocheck执行了---捡测,并在发生 Angular 无法或不愿意自己检测的变化时作出反应"
    );

    if (this.userinfo !== this.oldUserinfo) {
      console.log(`你从${this.oldUserinfo}改成${this.userinfo}`);
      this.oldUserinfo = this.userinfo;
    } else {
      console.log("数据没有变化");
    }
  }

  ngAfterContentInit() {
    console.log("04ngAftercontentInit执行了---当把内容投影进组件之后调用");
  }
  ngAfterContentChecked() {
    console.log(
      "05ngAftercontentchecked执行了---每次完成被投影组件内容的变更检测之后调用"
    );
  }
  ngAfterViewInit() {
    console.log(
      "06 ngAfterViewInit执行了----初始化完组件视图及其子视图之后调用(dom操作放在这个里面"
    );
  }
  ngAfterViewChecked() {
    console.log(
      "07ngAfterViewchecked执行了----每次做完组件视图和子视图的变更检测之后调用"
    );
  }
  ngOnDestroy() {
    console.log("08ngonDestroy执行了...");
  }

  changeMsg() {
    this.msg = "我是一个生命周期演示哦-- 我变了";
  }
}

效果图:

改变值触发哪些函数:如下

javascript 复制代码
<button (click)="changeMsg()">改变Msg</button>

销毁组件

八、Rxjs 异步数据流

中文手册:​​​​​https://cn.rx.js.org/

1、创建服务:ng g service services/request

2、引入服务

异步编程:

<----! request.service.ts ------->

javascript 复制代码
import { Injectable } from "@angular/core";

import { Observable } from "rxjs";

@Injectable({
  providedIn: "root",
})
export class RequestService {
  constructor() {}
  // 同步
  getData() {
    return "this is service data";
  }
  // 异步
  getCallbackData(cb) {
    setTimeout(() => {
      var username = "zhangsan";
      // return username
      cb(username);
    }, 1000);
  }
  // promise异步
  getPromiseData() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        var username = "zhangsan---promise";
        resolve(username);
      }, 2000);
    });
  }
  // Rsjx异步
  getRsjxData() {
    return new Observable((observer) => {
      setTimeout(() => {
        var username = "zhangsan---Rsjx异步";
        observer.next(username)
        // observer.error('错误数据')
      }, 2000);
    });
  }

  // 多次执行
  getPromisSeintervaleData() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        var username = "zhangsan---promise多次执行";
        resolve(username);
      }, 1000);
    });
  }
  getRxjsSeintervaleData() {
    let count = 0
    return new Observable<any>((observer) => {
      setInterval(() => {
        count++;
        var username = "zhangsan---Rsjx多次执行";
        observer.next(username)
        // observer.error('错误数据')
      }, 1000);
    });
  }

  getRxjsintervaleNum() {
    let count = 0
    return new Observable<any>((observer) => {
      setInterval(() => {
        count++;
        observer.next(count)
        // observer.error('错误数据')
      }, 1000);
    });
  }
}

<----! home.component.ts ------->

javascript 复制代码
import { Component, OnInit } from "@angular/core";
import { RequestService } from "../../services/request.service";

import { filter, map } from "rxjs/operators";

@Component({
  selector: "app-home",
  templateUrl: "./home.component.html",
  styleUrls: ["./home.component.css"],
})
export class HomeComponent implements OnInit {
  constructor(public request: RequestService) {}

  ngOnInit() {
    // 1、同步方法
    let data = this.request.getData();
    console.log(data);

    // 2、获取异步方法&数据
    this.request.getCallbackData((data) => {
      console.log(data);
    });

    // 3、promise异步
    var promiseData = this.request.getPromiseData();
    promiseData.then((data) => {
      console.log(data);
    });
    // 4、rxjs获取异步方法数据
    // var rxjsData = this.request.getRsjxData();
    // rxjsData.subscribe((data) => {
    //   console.log(data);
    // });

    // 5、rxjs unsubscribe取消订阅
    var streem = this.request.getRsjxData();
    var d = streem.subscribe((data) => {
      console.log(data);
    });
    setTimeout(() => {
      d.unsubscribe(); /* 取消订阅 */
    }, 1000);

    // 6、promise 执行多次(没有这个能力)
    var intervalData = this.request.getPromisSeintervaleData();
    intervalData.then((data) => {
      console.log(data);
    });

    // 7、Rxjs执行多次
    // var streemInterval = this.request.getRxjsSeintervaleData();
    // streemInterval.subscribe((data) => {
    //   console.log(data);
    // });

    // 8、用工具方法对返回数据进行处理
    /*
   
    //  filter
    var streemNum = this.request.getRxjsintervaleNum();
    streemNum.pipe(
      filter((value) => {
        if(value%2==0){
          return true
        }
      }),
    )
    .subscribe((data) => {
      console.log(data);
    });
   
   */

    /*
      // map
      var streemNum = this.request.getRxjsintervaleNum();
      streemNum.pipe(
        map((value) => {
        return value*value
        }),
      )
      .subscribe((data) => {
        console.log(data);
      });
    */

      // fliter & map 的结合使用
      var streemNum = this.request.getRxjsintervaleNum();
      streemNum.pipe(
        filter((value) => {
          if(value%2==0){
            return true
          }
        }),
        map((value) => {
          return value*value
        }),
      )
      .subscribe((data) => {
        console.log(data);
      });
  }
}

九、Http 请求

1、get 请求数据

2、post提交数据

3、jsonp 请求数据

十、使用axios 请求数据

asiox : https://github.com/axios/axios

1、创建服务

ng g service services/httpservice

2、安装:asiox

npm i axios --save

3、在服务中引入axios

4、组件中引入使用

十一、路由

1、创建组件

javascript 复制代码
ng g component components/home

ng g component components/news

ng g component components/product

2、引入组件

3、配置路由

接下来就是输入路径就可以切换页面了

4、routerLink跳转页面 默认路由

选中当前页面高亮

十二、动态路由 & get 传值

1、get 传值

1.1、跳转、引入路由

1.2、接收

2、动态路由传值

2.1、跳转

2.2、接收

效果:

十三、动态路由的 js 跳转路由

1、路由引入十二点一样

2、get 传值

十四、父子路由(嵌套路由)

1、效果图

2、创建组件&路由

html 复制代码
ng g component components/home
ng g component components/product
...
ng g component components/home/welcome

3、根组件路由跳转

4、左边路由跳转

5、右边显示内容使用<router-outlet></router-outlet>占位

6、需要选中高亮每个父组件都要加上

html 复制代码
routerLinkActive="active"

十五、vdemo项目

地址:https://gitee.com/xu-feiyu/angular-basice

仓库地址:https://gitee.com/xu-feiyu/angular-basice.git

相关推荐
想要打 Acm 的小周同学呀4 分钟前
前端组件化开发
前端·javascript·vue.js·组件化开发
鸡c14 分钟前
rabbitMq-----broker服务器
服务器·前端·rabbitmq
yqcoder36 分钟前
Vue3 指令详解
前端·javascript·vue.js
GoppViper1 小时前
互联网前后端分离的开发场景,一般会员和数据权限的判断是放在前端还是后端?
前端·后端·架构·golang·前后端分离
0wioiw01 小时前
web笔记
前端·笔记
CocoaAndYy1 小时前
Spring之生成Bean
java·前端·spring
前端李易安2 小时前
vue 项目中的配置文件(.env)的用法
前端·javascript·vue.js
yaoxin5211232 小时前
第三十五章 结合加密和签名
java·前端·网络
李小白662 小时前
操作系统第三章 内存管理概念(上)
java·服务器·前端
Front思2 小时前
vue3中el-input在form表单按下回车刷新页面
前端·javascript·vue.js