angular
1. 新建组件 ng n c hello
2. 插值语法 {{ content }}
3. 属性绑定用 []
<p-dataTable [value]="listdata" selectionMode="multiple"></p>
或者
<p-dataTable [value]="listdata" [selectionMode]="'multiple'"></p>
<div [class]="'box'"></div> // 必须是字符串 [class]="box"这样写box是变量
<h3 [class.xxy-table]="true"></h3> //
<h3 [class]="{'xxyTable': true}"></h3> //对象条件渲染
ngClass 是指令 和直接写class一样
<h3 [ngClass]="{'active': isActive}"></h3>
<h3 [class]="['xxyTable', 'xxyBox']"></h3> //数组渲染
<p [style]="{ width: '170px', height: '30px' }"></p> //样式绑定
ngStyle
4. 条件判断 ngIf
<p *ngIf="isShow"></p>
<ng-container *ngIf="isShow; else Show">
<p></p>
</ng-container>
<ng-template #Show>
<p></p>
</ng-template>
5. 循环语句
let elementDatas: string[] = ['小明', ‘小红]
<div *ngFor="let data of elementDatas let i = index">
{{i}} //下标
{{data}} // 值
</div>
6. 事件绑定
<button (click)="handleClick()"></button>
7. ViewChild 绑定获取dom元素 (类似vue2中的ref)
通过 ViewChild 装饰器 获取 dom
import { ViewChild } from "@angular/core";
<div #text1></div>
@ViewChild("text1") text1: ElementRef;
this.text1.nativeElement
8 表单的双向数据绑定 (和vue的v-model类似)
首先全局引入app.module.js
import {FormsModule} from "@angular/forms";
imports: [ FormsModule ]
使用
<input maxlength="20" placeholder="名称" [(ngModel)]="prodectName"
export class ShopchecklistComponent implements OnInit {
prodectName: string = ''
}
9.动态表单 (和第8点类似都是实现表单绑定)
首先全局引入app.module.js
import {ReactivFormsModule} from "@angular/forms";
imports: [ ReactivFormsModule ]
使用,要注册一个表单控件,就要导入 Formcontrol 类并创建一个 Formcontrol 的新实例,将其保存为类的属性。
<input type='text' [formControl]="productName" />
使用必须 .value
<p>{{productName.value}}</p>
import { FormControl } from '@angular/forms'
export class ShopchecklistComponent implements OnInit {
productName: FormControl = new FormControl('')
//修改值
updateName(val:string) {
this.productName.setValue(val)
}
}
10. 动态表单组(引入第9步的ReactivFormsModule)
使用 FormsGroup创建
<form [formGroup]="personMes" (submit)="OnSubmit()">
<input type="text" formControlName="name"><br>
<input type="text" formControlName="address"><br>
<button>提交</button>
</form>
import { FormControl, FormGroup } from '@angular/forms';
export class ReativeFormsComponent implements OnInit {
personMes: FormGroup = new FormGroup({
name: new FormControl(),
address: new FormControl()
})
OnSubmit(){
console.log(this.personMes.value)
}
}
11. 基础表单验证
(不常用)表单项使用required启用验证,#自定义名字="ngModel",模版引用变量
<form>
账号:<input type="text" required #nameInp="ngModel" [(ngModel)]="fromData.name">
<p>验证信息{{nameInp.valid}}</p> //返回布尔值
密码:<input type="text" required #passInp="ngModel" [(ngModel)]="fromData.password">
<p>验证信息{{passInp.valid}}</p> //返回布尔值
<button (click)="OnSubmit(nameInp)">提交</button>
</form>
export class ReativeFormsComponent implements OnInit {
fromData={
name: '',
password: ''
})
OnSubmit(val){
console.log(val)
}
}
状态 | 为true时的类 | 为false时的类 |
---|---|---|
控件已经被访问过 | Ng-touched | Ng-untouched |
控件值已经变化 | Ng-dirty | Ng-pristine |
控件值是有效的 | Ng-valid | Ng-invalid |
12. 自定义表单验证
引入 FormGroup, FormBuilder, Validators
<form [formGroup]="valiDataForm">
<input type="text" formControlName="userName"><br>
<p *ngIf="valiDataForm.get('userName')?.errors?.required">请输入6-18位名称</p>
<p *ngIf="valiDataForm.get('userName')?.errors?.minlength">长度在6-18位</p>
<input type="text" formControlName="password"><br>
<input type="text" formControlName="phone"><br>
<button (click)="OnSubmit()">提交</button>
</form>
import { FormControl, FormGroup, FormBuilder, Validators } from '@angular/forms';
constructor(private fb: FormBuilder) {} //注入方法
valiDataForm: FormGroup = this.fb.group({ //通过FormBuilder生成控件组
userName: ['', [Validators.required, Validators.maxLength(18), Validators.minLength(6)]],
password: ['', [this.passwordVal]],
phone: ['', [Validators.required, this.phoneVal]],
})
//自定义校验方法
passwordVal() {}
//自定义校验方法
phoneVal(phone: FormControl):object {
const value = phone.value || ''
if(!value) return { desc: '请输入手机号'}
const valid = /[0-9]{11}/.test(value)
return valid ? {} : {desc: '请输入正确的手机号'}
}
//提交时获取
OnSubmit() {
console.log(this.valiDataForm.get('userName')) //获取校验信息
}
13. 管道 (类似vue里的过滤器)
管道的作用就是传输,不同的管道具有不同的作用。
angular中自带的pipe函数
{{DateTime | date: 'yyyy-MM-dd HH:mm:ss'}}
export class EditTheDeclarationComponent implements OnInit {
DateTime: Date = new Date() //获取本地当前时间
}
常用的内置管道
管道 | 类型 | 功能 |
---|---|---|
DatePipe | 纯管道 | 日期格式化 |
JsonPipe | 非纯管道 | 使用JSON.stringify()将对象转成json字符串 |
UpperCasePipe | 纯管道 | 将文本中的字母全部转在大写 |
LowerCasePipe | 纯管道 | 将文本中的字母全部转成小写 |
TitleCasePipe | 将文本转换成标题格式 | |
DecimalPipe | 纯管道 | 数值格式化 |
CurrencyPipe | 纯管道 | 货币格式化 |
PercentPipe | 纯管道 | 百分比格式化 |
SlicePipe | 非纯管道 | 数组或字符串取切割 |
I18nPluralPipe | 根据expression的值匹配mapping中的值,并将匹配之后的值展示出来 | |
I18nSelectPipe | 根据expression匹配mapping中的值,并且返回|匹配之后的值 |
14. 生命周期
钩子函数 | 用途 | 触发时机 |
---|---|---|
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 销毁指令或组件之前立即调用。 |
15. 组件交互(类似vue3.0 setup语法糖写法)
https://blog.csdn.net/qq_37516758/article/details/129136190
- 父组件给子组件传值
父组件
1. 定义数据
export class ShopchecklistComponent implements OnInit {
messageTitle: string = '某某页面头'
}
2.父组件在调用子组件的时候传值
<app-title [messageTitle]="messageTitle"></app-title>
子组件 app-title
1.需要引入Input
import { Input } from '@angular/core';
2.接收值
export class TitleComponent {
@Input() messageTitle: string;
}
3.使用
<p>{{messageTitle}}</p>
- 子组件给父组件传值
子组件 app-child
1.引入Output 和 EventEmitter
import { Output,EventEmitter } from '@angular/core';
2.定义方法 handleChange
@Output handleChange = new EventEmitter();
3.执行方法并传递数据
send() {
this.handleChange.emit("给父组件传递的数据")
}
父组件
1.执行子组件emit出来的事件名字然后自定义事件
<app-child #child (handleChange)="handleChange($event)"></app-child>
handleChange(e: string) {
console.log(e, '获取子组件的值')
}
- 父组件获取子组件的数据(ViewChild)
父组件
<app-child #handleChild></app-child>
import { ViewChild } from "@angular/core";
@ViewChild("handleChild") handleChild : any;
假设有一个子组件方法为run()或者子组件数据为name
this.handleChild.run();
this.handleChild.name;
16. angular中服务与注入
https://blog.csdn.net/weixin_43536485/article/details/109466208
服务的作用:抽离js,例如封装http请求
- 输入以下命令创建服务,自动在service中创建2个文件hero.service.spec.ts跟hero.service.ts
ng g service service/hero
- hero.service.ts 中引入@Injectable装饰器
import { Injectable } from '@angular/core';
//@injectable的意思是声明该服务类可被注入到其他的service、component或者其他实例中去
@Injectable({
providedIn: 'root' //providedIn 声明服务提供给哪个模块使用,
//root 实际上是 AppModule 的别名,因此不需要额外导入 AppModule。
})
export class HeroService {
constructor() {}
get(){
return '这是服务里的数据'
}
}
- 在app.module.ts文件中声明服务
先import导入服务,再往providers数组中添加服务名
import {HeroService} from './service/hero.service';
//NgModule 最根本的意义是帮助开发者组织业务代码
//开发者可以利用 NgModule 把关系比较紧密的组件组织到一起
//来定义本模块的元数据
@NgModule({
//用来放组件、指令、管道的声明
declarations: [],
//用来导入项目中需要的模块
imports: [],
//需要使用的 Service 都放在这里。
providers: [
HeroService
],
})
- 注入组件中,在组件中使用
import { HeroService } from '../../service/hero.service' //导入服务文件
//这其实需要当做一个整体来看,上面一段被称作装饰器,用于装饰AppComponent这个class:
export class HomeComponent implements OnInit {
//也可以使用下面定义属性的来使用服务(不提倡)
//public heroService:HeroService = new HeroService();
constructor(public heroService:HeroService) { //把服务当作参数注入到构造函数中去
console.log(heroService.get()); //使用服务方法 因为在构造函数里,可以不用加this
}
getChild(){
console.log(this.heroService.get()); //使用服务里的方法
}
}
17. 路由
路由: https://blog.csdn.net/lwf3115841/article/details/128275051
嵌套(父子)路由: https://blog.csdn.net/I_r_o_n_M_a_n/article/details/115718843
路由query参数(编程式):https://www.cnblogs.com/leileilei/p/9697898.html