前端 -- angular快速入门

Angular是一个Google维护的JavaScript框架,用于构建Web应用。AngularCLI提供快速项目搭建,包括模块创建、代码分割、热部署等功能。文章详细介绍了组件的创建、生命周期方法,如ngOnChanges、ngOnInit等,以及组件间的通信方式,如@Input和@Output。此外,还讨论了服务的创建和使用,以及路由配置和导航。
摘要由CSDN通过智能技术生成

1、angular 介绍

Angular 是一个由 Google维护的开源JavaScript框架,用于在HTML和JavaScript中构建Web应用程序。它包括:

  1. Angular CLI 可以快速搭建框架,创建module,service,class,directive等;
  2. 具有webpack的功能,代码分割,按需加载;
  3. 代码打包压缩;
  4. 模块测试;
  5. 热部署,有改动立即重新编译,不用刷新浏览器;而且速度很快
  6. 有开发环境,测试环境,生产环境的配置,不用自己操心;
  7. sass,less的预编译Angular CLI都会自动识别后缀来编译;
  8. typescript的配置,Angular CLI在创建应用时都可以自己配置;
  9. 在创建好的工程也可以做一些个性化的配置,webpack的具体配置还不支持,未来可能会增加;
  10. Angular CLI创建的工程结构是最佳实践,生产可用。

2、angular安装

//安装脚手架
npm install -g angular-cli
//创建项目
ng new project_name(项目名称)
//启动项目
cd project_name
ng serve --open 

3、angular常用命令

内容命令
componentng g component 名称
dirctiveng g directive 名称
pipeng g pipe名称
seviceng g sevice名称
classng g class名称
interfaceng g interface名称
enumng g enum名称
moduleng g module名称

4、组件

1、创建组件

输入命令快速创建组件

ng g component 名称 
\\也可以简写 ng g c 名称

例如输入命令 ng g c hello
即可生成一个hello文件夹,其中有4个文件
在这里插入图片描述
.html文件为网页布局代码
.scss文件为样式代码
.spec.ts文件为单元测试代码
.ts文件为业务逻辑代码,需要编写ts类型

在 .ts文件中会生成如下代码

	@Component({
	  selector: 'app-hello',
	  templateUrl: './hello.component.html',
	  styleUrls: ['./hello.component.scss']
	})

selector:组件的命名
template:组件的内联模板
templateUrl:组件模板文件的 URL
styleUrls:组件样式文件
styles:组件内联样式

2、生命周期

​ Angular 会按以下顺序执行钩子方法。你可以用它来执行以下类型的操作。

钩子方法用途时机
ngOnChanges()当 Angular 设置或重新设置数据绑定的输入属性时响应。 该方法接受当前和上一属性值的 SimpleChanges 对象注意,这发生的非常频繁,所以你在这里执行的任何操作都会显著影响性能。ngOnInit() 之前以及所绑定的一个或多个输入属性的值发生变化时都会调用。注意,如果你的组件没有输入,或者你使用它时没有提供任何输入,那么框架就不会调用 ngOnChanges()
ngOnInit()在 Angular 第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。在第一轮 ngOnChanges() 完成之后调用,只调用一次
ngDoCheck()检测,并在发生 Angular 无法或不愿意自己检测的变化时作出反应。紧跟在每次执行变更检测时的 ngOnChanges() 和 首次执行变更检测时的 ngOnInit() 后调用。
ngAfterContentInit()当 Angular 把外部内容投影进组件视图或指令所在的视图之后调用。第一次 ngDoCheck() 之后调用,只调用一次。
ngAfterContentChecked()每当 Angular 检查完被投影到组件或指令中的内容之后调用ngAfterContentInit() 和每次 ngDoCheck() 之后调用
ngAfterViewInit()当 Angular 初始化完组件视图及其子视图或包含该指令的视图之后调用第一次 ngAfterContentChecked() 之后调用,只调用一次。
ngAfterViewChecked()每当 Angular 做完组件视图和子视图或包含该指令的视图的变更检测之后调用。ngAfterViewInit() 和每次 ngAfterContentChecked() 之后调用。
ngOnDestroy()每当 Angular 每次销毁指令/组件之前调用并清扫。 在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏在 Angular 销毁指令或组件之前立即调用。

3、组件通信

1、父向子传递数据

父组件通过@Input给子组件绑定属性设置输入类数据 (类似vue中的props)

//父组件
<app-hello  [name]="'小明'"></app-hello>

//子组件
import { Component, Input } from '@angular/core';
@Input()
  name!: string;
 ngOnInit(): void {
    console.log(this.name)
  }
2、子向父传递数据

子组件通过@Output弹射触发事件,再通过emit发送数据。
父组件再在子组件绑定相应的事件即可

//子组件
import { Component, Output,EventEmitter } from '@angular/core';
@Output() addList = new EventEmitter()
  pushList(v:string){
      this.addList.emit(v)
 }
 
//父组件
 <app-hello (addList)="addListFun($event)"  [name]="'小明'"></app-hello>
 
list:number[] = [1,2,3,4]
  addListFun(num:number){
    this.list.push(num)
  }

3、父组件触发子组件方法

angular中通过ViewChild获取子组件实例,获取子组件数据 (类似vue中的ref)

//给子组件绑定 #mychild
<app-hello #myChild  [name]="'小明'"></app-hello>
<button (click)="getView($event)">获取</button>

@ViewChild('myChild') child: any;
  constructor() { }
  getView(e:any){
    this.child.setInpValue('我是一段数据')
  }

5、模板

1、插值语法

<h3>hello {{ name }}</h3>

2、属性绑定

1、id绑定
<h3 [id]="'new-Id'">hello</h3>
2、 class类绑定
//单一类绑定
<h3 [class.new-Dom]="true">hello</h3>

//多重类绑定
<h3 [class]="'new-Dom title-dom min-title'">hello</h3>
<h3 [class]="{'new-Dom':true,'title-dom':false}">hello</h3>
<h3 [class]="['new-Dom','title-dom']">hello</h3>

//ngClass写法
<h3 [ngClass]="{'active': isActive}">hello {{ 1+1 }}</h3>
3、行内样式style绑定
//单一样式绑定
<h3 [style.width]="'300px'">hello</h3>

//带单位的单一样式绑定
<h3 [style.width.px]="'300'">hello</h3>

//多重样式绑定
<h3 [style]="'background:red;color:#fff'">hello</h3>
<h3 [style]="{'background':'red','color':'#fff'}">hello</h3>

//ngStyle写法
<h3 [ngStyle]="{'color': 'red'}">hello</h3>
<h3 [ngStyle]="{'font-size': isMax ? '24px' : '12px'}">hello</h3>

3、条件判断

ngIf是直接影响元素是否被渲染,而非控制元素的显示和隐藏

<div *ngIf="isMax">Max title</div>
<div *ngIf="isMin">Min title</div>

ngSwitch判断

<ul [ngSwitch]="status">
    <li *ngSwitchCase="1">已支付</li>
    <li *ngSwitchCase="2">订单已经确认</li> 
    <li *ngSwitchCase="3">已发货</li>
    <li *ngSwitchDefault>无效</li>
  </ul>

4、循环语句

<div *ngFor="let color of colors let i=index let odd=odd">
  {{odd}}
  {{i}}
  {{color}}
</div>

odd是布尔值,指示当前索引是否是偶数索引

5、事件绑定

<button (click)="onSave($event)">Save</button>
export class AppComponent {
   onSave(){
       console.log('点击了按钮')
   }
}

6、数据双向绑定

<div>
    输入: <input [(ngModel)]="userName">
	<h1>你输入了: {{userName}}</h1>
</div>
export class AppComponent {
  userName='';
}

7、模板引用变量

在模板中,要使用 # 来声明一个模板变量。(类似vue中的ref)下列模板变量 #userName 语法在 <input> 元素上声明了一个名为 userName 的变量

<input #userName placeholder="请输入用户名" />

可以在组件模板中的任何地方引用某个模板变量

<button (click)="callUserName(userName.value)">Call</button>

export class AppComponent {
   callUserName(v){
       console.log(v)
   }
}
  • 如果在组件上声明变量,该变量就会引用该组件实例。
  • 如果在标准的 HTML 标记上声明变量,该变量就会引用该元素。
  • 如果你在 <ng-template> 元素上声明变量,该变量就会引用一个 TemplateRef 实例来代表此模板。

8、表单控件

要注册一个表单控件,就要导入 FormControl 类并创建一个 FormControl 的新实例,将其保存为类的属性。

 <input type="text" [formControl]="name">
 <p>Value: {{ name.value }}</p>
import { FormControl } from '@angular/forms';

export class NameEditorComponent {
  name = new FormControl('');
}

修改name值可以通过FormControl 提供的 setValue() 方法

 updateName() {  this.name.setValue('Tina');}

9、表单控件分组

表单中通常会包含几个相互关联的控件。响应式表单提供了两种把多个相关控件分组到同一个输入表单中的方法。
要将表单组添加到此组件中,请执行以下步骤。

  1. 创建一个 FormGroup 实例。
  2. 把这个 FormGroup 模型关联到视图。
  3. 保存表单数据。

创建一个 FormGroup 实例

在组件类中创建一个名叫 loginForm 的属性,并设置为 FormGroup 的一个新实例。要初始化这个 FormGroup,请为构造函数提供一个由控件组成的对象,对象中的每个名字都要和表单控件的名字一一对应

import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';

@Component({
  selector: 'app-profile-editor',
  templateUrl: './profile-editor.component.html',
  styleUrls: ['./profile-editor.component.css']
})
export class ProfileEditorComponent {
  loginForm = new FormGroup({
    userName: new FormControl(''),
    password: new FormControl(''),
  });
}

//模板渲染
<form [formGroup]="loginForm">
  
  <label>
    账号:
    <input type="text" formControlName="userName">
  </label>

  <label>
    密码:
    <input type="text" formControlName="password">
  </label>

</form>

10、表单验证

1、普通验证

表单元素添加required关键字表示必填,通过绑定ngModel的引用可以拿到到当前组件的信息,通过引用获取到验证的信息

<form  action="">
    账号:<input required #nameInp="ngModel" type="text" [(ngModel)]="fromData.name" name="userName">
    <br>
    <span>{{nameInp.valid }}</span>
    <hr>
    密码:<input required  #pasInp="ngModel" type="text" [(ngModel)]="fromData.password" name="password">
    <br>
    <span>{{pasInp.valid }}</span>
    <hr>
    <button (click)="subBtnFUn(nameInp)">提交</button>
</form>

export class AppComponent {
    fromData={
       name:'',
       password:''
    };

    subBtnFUn(obj){
      console.log(obj)
    }
}
2、自定义验证
import { FormGroup, FormBuilder,Validators } from '@angular/forms';

//构造函数里注入FormBuilder
constructor(private fb:FormBuilder) { }

//错误提醒数据
formErrors = {
  'title': '',
  'content': ''
};


//在组件类的初始化函数里对表单中的元素的校验进行定义,并调用表单的valueChanges方法,检测表单的输入的变化
ngOnInit():void {
  this.taskInfo.isComplete = 1;
  this.tasksForm = this.fb.group({
     userName: ['', [Validators.required,
    				 Validators.maxLength(18),
                     Validators.minLength(6) ] ],
    password: ['', [this.passWordVal]],
    phone: ['', [Validators.required,this.phoneVal],]
  });

  phoneVal(phone: FormControl): object {
    const value = phone.value || '';
    if(!value) return  {desc:'请输入手机号'}
    const valid =  /[0-9]{11}/.test(value);
    return valid ? {} :{desc:'联系电话必须是11位数字'}
  }
  passWordVal(password:FormControl):object{
    const value = password.value || '';
    const valid = value.match(/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/);
    return valid ? {} : {passwordValidator: {desc:'密码至少包含 数字和英文,长度6-20'}}
  }
}

11、管道

管道的作用就是传输。不同的管道具有不同的作用。(其实就是处理数据,类似vue2中的filter)
常用管道如下:

管道功能
DatePipe日期管道,格式化日期
JsonPipe将输入数据对象经过JSON.stringify()方法转换后输出对象的字符串
UpperCasePipe将文本所有小写字母转换成大写字母
LowerCasePipe将文本所有大写字母转换成小写字母
DecimalPipe将数值按照特定的格式显示文本
CurrentcyPipe将数值进行货币格式化处理
SlicePipe将数组或者字符串裁剪成新子集
PercentPipe将数值转百分比格式

注意管道要小写

<p>{{ 'Angular' | uppercase }}</p>
<p>{{dateStr | date:'yyyy-MM-dd HH:mm:ss'}} </p>

6、服务

angular中,把从组件内抽离出来的代码叫服务,服务的本质就是函数

官方认为组件不应该直接获取或保存数据, 它们应该聚焦于展示数据,而把数据访问的职责委托给某个服务。而服务就充当着数据访问,逻辑处理的功能。把组件和服务区分开,以提高模块性和复用性。通过把组件中和视图有关的功能与其他类型的处理分离开,可以让组件类更加精简、高效。

使用命令ng g s xxx创建一个服务,通过**@Injectable()**装饰器标识服务。

//导入Injectable装饰器
import { Injectable } from '@angular/core';
//使用Injectable装饰器声明服务
@Injectable({
  //作用域设定,'root'表示默认注入,注入到AppModule里
  providedIn: 'root',
})
export class TestService {
}

依赖注入

在这个例子中,providedIn: 'root' 指定 Angular 应该在根注入器中提供该服务,从而实现根注入器将服务注入,它就在整个应用程序中可用了。

  • ​ ‘root’ :注入到AppModule,提供该服务,所有子组件都可以使用(推荐)
  • ​null : 不设定服务作用域(不推荐)
  • 组件名:只作用于该组件(懒加载模式)

服务文件

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class TestService {
	constructor() {}
	list:Array<string>=['angular','react','vue']
	getList(){
		return this.list
	}
}

调用服务的文件

import { Component, OnInit } from '@angular/core';
import {ListService} from '../hero.service'

@Component({
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.scss'],
  providers: [ListService]
})
export class TestComponent implements OnInit {

  constructor(private ListService:ListService) { }
  list:Array<string> | undefined

  ngOnInit(): void {
  	this.list = this.ListService.getList()
  }
}

7、路由

路由器是一个调度中心,它是一套规则的列表,能够查询当前URL对应的规则,并呈现出相应的视图.

路由是列表里面的一个规则,即路由定义,它有很多功能字段:

  • path字段,表示该路由中的URL路径部分
  • Component字段,表示与该路由相关联的组件

每个带路由的Angular应用都有一个路由器服务的单例对象,通过路由定义的列表进行配置后使用。

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import {HomeComponent} from './home/home.component'

const routes: Routes = [
 {path:'home',component:HomeComponent}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
//路由导航 
<a [routerLink]="['/home']">home</a>
<a [routerLink]="['/hello']">hello</a>

//组件渲染输出
<router-outlet></router-outlet>

1、路由嵌套

const routes: Routes = [
    {path:'home',
      component:HomeComponent,
      children:[
        {path:'hello',component:HelloComponent}
      ]
    },
];

home Component内这是router-outlet路由出口,即可在home 路由内渲染子级路由

//home template
<h2>home Component</h2>
<a [routerLink]="['/home/hello']">hello</a>
<router-outlet></router-outlet>

2、路由传参

1、query

在a标签上添加一个参数queryParams,并通过this.routerinfo.snapshot.queryParams获取参数

<a [routerLink]="['/hello']" [queryParams]="{id:3}" >hello</a>
import {ActivatedRoute} from '@angular/router';
constructor(private routerinfo:ActivatedRoute) { }

 ngOnInit() {
  //id为参数名字
    this.id=this.routerinfo.snapshot.queryParams["id"]
  }
2、param

修改路由配置文件path,路由导航a标签routerLink后面数组的第二个参数为传递的值,并且通过subscribe请阅的方式获取name参数。

 {
    path: 'hello/:name',
    component:HelloComponent,
  },
//我们在后面添加/:name此时name即为传递的参数名字
//a标签设置如下,注意顺序不可错乱。
<a [routerLink]="['/hello','我是url传递参数']" [queryParams]="{id:3}" >hello</a>
ngOnInit() {
    this.routerinfo.params.subscribe((params:Params)=>{
      this.name=params['name']
    })
  }
  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
想要从零开始学习Web前端开发,你需要掌握以下几个方面: 1. HTML:HTML 是网页的基础语言,它定义了网页的结构和内容。学习 HTML 可以帮助你了解网页的基本结构和元素,以及如何使用标签、属性和样式来创建网页。 2. CSS:CSS 是网页的样式表语言,它可以控制网页的外观和布局。学习 CSS 可以帮助你了解如何使用样式来美化网页,包括颜色、字体、背景等方面。 3. JavaScriptJavaScript 是网页的脚本语言,它可以为网页添加交互和动态效果。学习 JavaScript 可以帮助你了解如何处理用户输入、操作 DOM 元素、发送网络请求等常见操作。 4. 前端框架:前端框架是一种提供了高级工具、组件和模板的库,可以帮助你更快速地开发网页。常见的前端框架有 React、Vue 和 Angular 等。 推荐的学习路线如下: 1. 先学习 HTML 和 CSS,这是入门的基础,可以通过在线教程或者视频课程进行学习。 2. 学习 JavaScript,这是实现交互和动态效果的必备技能,可以通过阅读书籍或者参加线上课程进行学习。 3. 学习前端框架,这可以大大提高开发效率和代码质量。建议选择一种主流的框架进行深入学习。 4. 参加实战项目和社区活动,这可以帮助你将所学知识应用到实际项目中,同时也可以结交志同道合的朋友和行业专家,获取更多学习和成长的机会。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值