前端框架Angular学习笔记
配置环境
环境的配置比较简单,但是可能个别地方会遇到问题,这里不再详细说了,推荐几篇博客和学习资料,上面有详细步骤可供参考(第三篇是某个常见问题的解决方案,本篇笔记主要是观看第四项大地老师的视频所做)。
1.【前端】Angular8入门教程笔记+Angular material安装与使用
2. Angular 搭建本地开发环境,并在VSCode运行第一个Angular项目
3. 无法将“node.exe”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
4. 链接:百度网盘-Angular学习资料-大地老师 提取码:vm4r
创建新项目和导入项目
创建新项目
假设创建的新项目名称为angulardemo03,我们可以通过执行以下命令来执行:
ng new angulardemo03 --skip-install
“–skip-install”表示的是只创建新项目,不安装对应的依赖。
导入项目
需要注意的是,导入项目之前,需要先弄清楚要导入的项目使用的Angular是什么版本,假设版本不一致,我们需要在本机环境,重新配置全局的指定版本的Angular环境。具体操作可以参考下面这篇博客:
/ItTvibe/article/details/79062838
之后,我们就可用以下命令来进行node_modules的安装了:
npm install
或:
cnpm install
测试运行项目
使用如下命令测试运行项目(–open表示运行时自动打开网页):
ng serve --open
自定义组件
官方网站的介绍:
https://angular.io/cli
使用的命令:ng g component <组件路径/名称>
例如:
ng g component component/news
若不指定路径,则会默认在app目录下创直接创建新组建。
执行此命令之后,就会看到app目录下生成一个component/news的文件夹,代表组件已创建成功。
使用命令创建组件的好处是在app.module.ts文件中会自动把新创建的组件引入,并配置在@ng.Moudule中,因此无需手动在app.module.ts文件中引入。
打开app/component/news/ponent.ts,我们可以看到@component({})中selector属性,其值“app-news”就是我们新定义的组件的名称,如下图所示。
tu图1
假如我们要在根组件(ponent.html)中调用新创建的news组件,只需要在ponent.html中加入<app-news></app-news>标签即可,如下图。
为了便于测试,可以先在ponent.html中写点东西:
<h2>我是一个新闻组件</h2>
或者直接通过数据绑定(因为图1中所示的ts代码中最后几行已经定义了数据,变量为“title”)
<h2>{{title}}</h2>
这里顺便提一下,ts中建议用以下方式(标准方式)指定数据:
public student:any='我是一个学生的属性(数据)';
public是权限修饰符,其他还有protected,private,与java中的类似,
变量名冒号后面指定数据类型,any代表任意类型。
注:ts中定义变量时不同于js,前面不能加var声明变量。
获取和改变属性值
刚刚简要提到了定义属性的方式,定义时可以赋初值,也可以不手动赋值,可以再构造方法constructor{}中,使用this.<变量>的形式给属性赋值。
比如定义news组件后,在ponent.ts文件中这样写:
import {Component, OnInit } from '@angular/core';@Component({selector: 'app-news',templateUrl: './ponent.html',styleUrls: ['./ponent.scss']})export class NewsComponent implements OnInit {msg='我是一个新闻组件的msg';//推荐的标准定义方式:public student:any='我是一个学生的属性(数据)';public userinfo={username:"张三",age:'20'}public message:any;constructor() {this.message='这是给属性赋值--(改变属性的值)';//获取属性的值并在前端输出(在浏览器按F12可以在console中看到)console.log(this.msg); //改变属性的值this.msg="我是改变后的msg的值";}ngOnInit() {}}
绑定数据、属性
绑定数据的方式上文已经介绍过了,Angular框架中的TypeScript定义属性时可以指定很多种数据类型,具体数据类型可以参看下面这篇文章:
Angular 4入门教程系列:11:TypeScript:基础数据类型
假设在ponent.ts文件中定义了
public title='我是新闻组件';
那么我们如果在ponent.html中的<h2></h2>标签绑定数据时,只需
<h2>{{title}}</h2>
即可。
绑定属性分为静态绑定和动态绑定。静态绑定可以这样写:
<div title="我是一个div">鼠标瞄上去看一下</div>
而动态绑定所绑定的属性值来自于ts,假设在ts中定义这样的属性:
public student:any='我是一个学生的属性(数据)';
那么在html的div标签中绑定该属性时,可以这样绑定:
<div [title]="student"> 张三</div>
[innerHTML]表示解析属性值中的HTML标签。
数据循环
普通数组的数据循环
假设ts中定义了数组属性:
public arr=['1111',2222,'33333'];
或:
public arr:any[]=['1111',2222,'33333'];
或:
public arr:Array<any>=['1111',2222,'33333'];
html中可以通过*ngFor指令,这样进行数组的数据循环(<ul>表示无序循环,<ol>表示有序循环):
<ul><li *ngFor="let item of arr">{{item}}</li></ul>
显示数据的索引值
ponent.ts:
public list:any[]=[{"title":'我是新闻1'},{"title":'我是新闻2'},{"title":'我是新闻3'}];
ponent.html:
<h1>循环数据 显示数据的索引(key)</h1><ul><li *ngFor="let item of list;let key=index;">{{key}}---{{item.title}}</li></ul>
包含对象数组的数据循环
假设ts中定义了这样的数组:
public userlist:any[]=[{username:'张三',age:20},{username:'李四',age:21},{username:'王五',age:40}];
我们在html中这样进行数据循环:
<ul><li *ngFor="let item of userlist">{{item.username}}---{{item.age}}</li></ul>
运行效果:
引入图片
引入本地图片
首先将需引入的图片放入src/assets/images中:
然后假设我们在ponent.html中需要将其引入,那么使用这样的语句即可:
<h1>引入图片</h1><img src="assets/images/02.png" alt="收藏" />
看下运行效果:
引入远端图片
需要把业务逻辑中定义的指定链接的图片数据渲染到页面上。
在ponents.ts文件中定义属性:
public picUrl='/img/superlogo_c4d7df0a003d3db9b65e9ef0fe6da1ec.png';
在ponent.html中将其引入:
<img [src]="picUrl" />
条件判断
*ngIf指令
例1
ponents.ts中:
public flag:boolean=true;
ponent.html中:
<h1>条件判断语句 *ngIf</h1><div *ngIf="flag"><img src="assets/images/02.png" /></div><div *ngIf="!flag"><img src="assets/images/01.png" /></div>
例2
ponent.ts:
public list:any[]=[{"title":'我是新闻1'},{"title":'我是新闻2'},{"title":'我是新闻3'}];
ponent.html:
<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>
运行结果:
*ngSwitch指令
ponents.ts中:
public orderStatus:number=3; /* 1表示已经支付 2支付并且确认订单 3、表示已经发货 4表示已经收货 其他、无效*/
ponents.html中:
<h1>条件判断语句 *ngSwitch</h1><span [ngSwitch]="orderStatus"><p *ngSwitchCase="1">表示已经支付</p><p *ngSwitchCase="2">支付并且确认订单</p><p *ngSwitchCase="3">表示已经发货</p><p *ngSwitchCase="4">表示已经收货</p><p *ngSwitchDefault>无效订单</p></span>
绑定属性
属性[ngClass]和[ngStyle]
Angular中改变某个标签的class属性不建议用DOM操作(不同于js和jQuery)。
[ngClass]
ponents.scss中:
img{max-width: 200px;}.red{color:red;}.blue{color: blue;}.orange{color: orange;}
ponents.html中:
<div class="red"> ngClass演示 (尽量不要用dom来改变class)</div><div [ngClass]="{'blue':true,'red':false}">ngClass演示</div><hr> <div [ngClass]="{'orange':flag,'red':!flag}">ngClass演示</div><strong>循环数组,让数组的第一个元素的样式为red ,第二个为orange</strong><ul><li *ngFor="let item of list;let key=index;" [ngClass]="{'red':key==0,'orange':key==1,'blue':key==2}">{{key}}---{{item.title}}</li></ul>
运行效果:
[ngStyle]
ponents.ts中:
public attr:string='orange';
ponents.html中:
<p style="color:red">我是一个p标签</p><p [ngStyle]="{'color':'blue'}">我是一个p标签</p><p [ngStyle]="{'color': attr}">我是一个p标签 </p>
运行效果:
管道
管道常用于将日期格式转换为用户友好的格式。
默认情况下显示的日期和时间:
我们可以通过管道转换一下,在ponents.html中:
<h1>管道</h1>{{today | date:'yyyy-MM-dd HH:mm ss'}}
运行结果:
也可以自定义管道,更详细的管道用法可参考一下链接:
angular中的管道(pipe) 以及自定义管道-适用于angular4 angualr5 angualr6 angular7
执行事件
事件
点击按钮组件可以触发事件。例如:
ponents.html:
<button (click)="run()">执行事件</button><br> <br> <button (click)="getData()">执行方法获取数据</button><br> <br> <button (click)="setData()">执行方法改变属性里面的数据</button><br> <br> <button (click)="runEvent($event)">执行方法获取事件对象</button>
ponents.ts:
run(){alert('这是一个自定义方法')}getData(){alert(this.title);}setData(){this.title='我是一个改变后的title';}runEvent(event:any){//ionic必须这样写,建议指定类型let dom:any=event.target; dom.style.color="red";}
这样写的代码执行后会看到html中定义的不同的按钮,拿“执行事件”为例,根据ts文件中绑定的事件,点击后会弹出一个alert对话框:
表单事件和事件对象
比如触发键盘事件并监听按下的是哪个键,这就需要监听键盘事件。
ponents.html:
keyDown<input type="text" (keydown)="keyDown($event)" /><br>keyUp:<input type="text" (keyup)="keyUp($event)" />
ponents.ts:
keyDown(e:any){if(e.keyCode==13){console.log('按了一下回车')}else{//e.target 获取dom对象console.log(e.target.value);}}keyUp(e:any){if(e.keyCode==13){console.log(e.target.value);console.log('按了一下回车');} }changeKeywords(){this.keywords='我是改变后的值';}getKeywords(){console.log(this.keywords)}
执行结果:每次在输入框中输入一些内容,假设按了下回车键,就会在浏览器前端获取到输入框中的值并打印,且会输出“按了一下回车”。通过e.target可以获取dom对象。
双向数据绑定
MVVM只是针对表单。首先需要在app.module.ts中引入@angular/forms模块:
import {FormsModule } from '@angular/forms';
(1)首先m->v:model改变会影响视图。比如在html中这样定义:
<input type="text" [(ngModel)]='keywords' />{{keywords}}<br><br><button (click)="changeKeywords()">改变keywords的值</button><br><br><button (click)="getKeywords()">获取keywords的值</button>
在改变input框里的值时,该值会被赋给{{keywords}}。
(2)其次,v->m:视图改变会反过来影响model。
比如,在ts中给keywords赋初值:
public keywords:string='这是默认值';
每当页面一刷新,model上的{{keywords}}值就会被赋给input框。当然也可以自定义一个方法更改keywords的值。
通过dom或双向数据绑定获取输入组件中的值
通过dom的方式
<input type="text" id="username" />
doSubmit(){let usernameDom:any=document.getElementById('username');console.log(usernameDom.value); }
通过双向数据绑定的方式
还是要先引入表单相关的模块
[]表示绑定属性,()表示绑定事件。
通过json管道“{{peopleInfo | json}}”可以把表单信息标准化为json数据:
<div class="people_list"><ul><li>姓 名:<input type="text" id="username" [(ngModel)]="peopleInfo.username" value="fonm_input" /></li><li>性 别:<input type="radio" value="1" name="sex" id="sex1" [(ngModel)]="peopleInfo.sex"> <label for="sex1">男 </label><input type="radio" value="2" name="sex" id="sex2" [(ngModel)]="peopleInfo.sex"> <label for="sex2">女 </label></li><li>城 市:<select name="city" id="city" [(ngModel)]="peopleInfo.city"><option [value]="item" *ngFor="let item of peopleInfo.cityList">{{item}}</option></select></li><li>爱 好:<span *ngFor="let item of peopleInfo.hobby;let key=index;"><input type="checkbox" [id]="'check'+key" [(ngModel)]="item.checked"/> <label [for]="'check'+key"> {{item.title}}</label> </span></li><li>备 注:<textarea name="mark" id="mark" cols="30" rows="10" [(ngModel)]="peopleInfo.mark"></textarea></li></ul><button (click)="doSubmit()" class="submit">获取表单的内容</button><br><br><br><br><pre>{{peopleInfo | json}}</pre></div>
public peopleInfo:any={username:'',sex:'2',cityList:['北京','上海','深圳'],city:'上海',hobby:[{title:'吃饭',checked:false},{title:'睡觉',checked:false},{title:'敲代码',checked:true}],mark:''}doSubmit(){console.log(this.peopleInfo)}
在css文件中稍微调下位置:
.people_list{width: 400px;margin: 40px auto;padding:20px;border:1px solid #eee;li{height: 50px;line-height: 50px;.fonm_input{width: 300px;height: 28px;}}.submit{width: 100px;height: 30px;float: right;margin-right: 50px;margin-top:120px;}}
运行结果:
在输入面板的组件上输入或选中某值时,下面页面会实时变化。点击获取表单数据会在浏览器控制台输出表单的值。
---------------------------我是分割线,未完待续--------------------