什么是 Angular
?
官网描述:Angular
是一个应用设计框架 与开发平台,旨在创建高效而精致的单页面应用。
设计框架 ?
与传统的库 (e.g
JQuery
,Zepto
) 不同,Angular 提供了一套声明式的编程规范帮助我们更规范,更高效地编写一个应用程序开发平台?
和其他的声明式框架 (
Vue
,React
) 不同,Angular
自身提供了丰富的 API 和解决方案(模块,请求,表单,路由,依赖注入。。。)来帮助我们完成几乎所有的业务能力上的开发 总体来说,Angular
是一个高度集成,API 丰富,设计极其优秀的框架级 Web 解决方案Angular 的官网
- 中文网:angular.cn
- 新的官网:angular.dev
学习 Angular 之前的前置知识:
HTML
,CSS
,ECMAScript
,DOM
,BOM
TypeScript
说说怎么安装 Angular
这里主要介绍 脚手架 构建 Angular
项目
脚手架安装
- 全局安装
Angular
的脚手架@angular/cli
shell
# npm 安装
npm install -g @angular/cli
# yarn 安装
yarn global add @angular/cli
# pnpm 安装
pnpm install -g @angular/cli
- 使用脚手架命令创建一个
Angular
项目
shell
# ng new xxx (xxx -> 项目名称)
ng new my-first-ng-project
- 打开项目,使用
ng serve
启动项目,启动完成后在浏览器输入http://localhost:4200
打开项目
Angular
脚手架构建出来的项目结构
shell
my-first-ng-project
|- .angular # angular 脚手架的构建产物 (ng build)
|- .vscode # vscode 编辑器配置文件
|- node_modules # 项目依赖
|- src # 项目源码
|- app # app 组件文件夹
|- app.component.html # App 组件的模板
|- app.component.scss # App 组件的样式
|- app.component.ts # App 组件的逻辑
|- app.config.ts # App 组件的整体配置
|- assets # 项目静态资源
|- favicon.ico # 项目图标
|- index.html # 入口模板文件
|- main.ts # 项目入口脚本
|- styles.scss # 全局演示文件
|- .editorconfig # 编辑器配置文件
|- .gitignore # git 提交时忽略什么
|- package.json # 项目依赖表
|- README.md # 脚手架生成的说明文件
|- tsconfig.app.json # app 中的 TypeScript 配置文件
|- tsconfig.json # 项目整体的 TypeScript 配置文件
|- tsconfig.spec.json # *.sepc 的 TypeScript 配置文件
写一个 Counter 小例子尝鲜
写一个 Counter 组件
counter.component.html
html
<main class="main">
<div class="container">
Hello
<div class="counter">
<h1>{{ count }}</h1>
<button (click)="addCount()">Add Count</button>
</div>
</div>
</main>
counter.component.scss
css
.counter button {
border: none;
outline: none;
padding: 6px 10px;
box-sizing: border-box;
box-shadow: 0 0 2px #ddd;
border-radius: 3px;
}
counter.component.ts
ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule],
templateUrl: './counter.component.html',
styleUrl: './counter.component.scss',
})
export class AppComponent {
public count: number = 0;
addCount() {
this.count += 1;
}
}
counter.config.ts
ts
import { ApplicationConfig } from '@angular/core';
export const appConfig: ApplicationConfig = {
providers: []
};
再写一个 TodoList
- todo-list.component.html
html
<div class="todo-list">
<div class="add-input">
<h1>{{ addInputValue }}</h1>
<!-- 1. 数据的单向流 -->
<!-- <input
type="text"
placeholder="请输入"
[value]="addInputValue"
(input)="handleInputChange($event)"
/> -->
<!-- 数据的双向绑定 -->
<input
type="text"
placeholder="请输入待办项"
[(ngModel)]="addInputValue"
/>
<button (click)="handleAddTodo()">确认添加</button>
</div>
<ul class="list">
<li
class="list-item"
*ngFor="let item of list"
>
<input type="checkbox" [checked]="item.completed" (change)="handleToggleTodo(item.id)" />
<span class="">{{ item.content }}</span>
<button (click)="handleRemoveTodo(item.id)">删除待办</button>
</li>
</ul>
</div>
- todo-list.component.ts
ts
import {
Component,
EventEmitter,
Input,
Output,
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
interface ITodo {
id: number;
content: string;
completed: boolean;
}
@Component({
selector: 'todo-list',
standalone: true,
imports: [CommonModule, FormsModule],
templateUrl: './todo-list.component.html',
styleUrl: 'todo-list.component.scss',
})
export default class TodoListComponent {
@Input()
public addInputValue: string = '';
@Output()
public addInputValueChange = new EventEmitter<string>();
public list: ITodo[] = [];
public handleAddTodo(): void {
const content: string = this.addInputValue.trim();
if (!content) {
window.alert('添加的内容不能为空!');
return;
}
const newItem: ITodo = {
id: new Date().getTime(),
content,
completed: false,
};
this.list = [newItem, ...this.list];
this.addInputValue = '';
}
public handleInputChange(e: Event): void {
const el: HTMLInputElement = e.target as HTMLInputElement;
const addInputValue: string = el.value;
this.addInputValue = addInputValue;
}
public handleToggleTodo(id: number) {
this.list = this.list.map(item => {
if (item.id === id) {
item.completed === !item.completed;
}
return item;
});
}
public handleRemoveTodo(id: number) {
this.list = this.list.filter(item => item.id !== id);
}
}
最后
到这里就结束了,感觉还是蛮好用的,具体的 API 还是得都看看文档