Angular 快速入门:从零搭建你的第一个应用

Angular 快速入门:从零搭建你的第一个应用

1. Angular 到底是什么?

你可能听过 Angular,也可能在纠结"学 Angular 还是学 React"。在动手之前,我们先花两分钟搞清楚它到底是什么。

Angular 是一个前端框架,而且是那种"全家桶"式的框架。

什么意思呢?打个比方:

  • React 像一家只卖面粉的店。你买了面粉回去,想蒸馒头、擀面条、包饺子,都得自己再买其他工具和材料。
  • Vue 像一家半成品的超市。馒头坯子、切好的菜都有,但有些调料你得自己去配。
  • Angular 像一份外卖套餐。米饭、菜、汤、餐具全给你配齐了,打开就能吃。

Angular 把路由、HTTP 请求、表单处理、依赖注入、模块化这些东西全部内置了。你不需要像 React 那样去纠结"用 React Router 还是用 Next.js",也不需要像 Vue 那样去选"用 Vue Router 还是 Pinia"。Angular 直接给你一套官方方案。

这意味着两件事:

好处:团队不用吵架选技术方案了。Angular 项目里,大家的写法高度统一,换人接手代码的成本低很多。

坏处:学习曲线相对陡。因为 Angular 给你的东西多,你得先理解它的"世界观"才能上手。不像 React,你懂 JavaScript 就能开始写。

所以 Angular 特别适合大型企业级应用严肃的多人团队。你很少看到个人博客用 Angular,但很多银行的内部系统、企业管理后台、Google 自己的产品(比如 Google Cloud Console)都是 Angular 写的。

对了,我说的 Angular 是 Angular 2 之后的版本,不是那个老掉牙的 AngularJS(1.x)。这两个东西差别巨大,如果你搜资料看到 AngularJS,直接绕开。

另外,这篇教程基于 Angular 17+ ,也就是默认使用 standalone(独立组件)模式的版本。如果你用的 Angular 版本更老,项目里会多出一个 app.module.ts,我会在第 3 节简单提一下。

2. 开工:装环境、建项目

聊完了概念,直接上手。第一步,装 Angular 官方提供的命令行工具------Angular CLI。

bash 复制代码
npm install -g @angular/cli

装完之后,你就有 ng 这个命令了。用它来创建一个新项目:

bash 复制代码
ng new todo-app

这时候 CLI 会问你几个问题:

  • Would you like to add Angular routing?y。路由后面会用到。
  • Which stylesheet format would you like to use?CSS,最简单。

然后等它安装依赖。创建完成后:

bash 复制代码
cd todo-app
ng serve

浏览器打开 http://localhost:4200,你就能看到一个默认页面。

就这么简单,你的第一个 Angular 应用已经跑起来了。

如果你用过 Vue 的 vue create 或者 React 的 create-react-app,会发现流程几乎一样。区别在于 Angular CLI 默认就给你配好了 TypeScript、测试框架、lint 工具------又是"全家桶"的体现。

3. 项目里都有啥?

用编辑器打开 todo-app 目录,你可能会被一堆文件吓到。别慌,大部分文件你以后才会接触到,现在只需要关注 src/ 下面的几个关键文件:

复制代码
src/
├── main.ts              # 应用的入口,启动整个应用
├── index.html           # 主页 HTML
├── styles.css           # 全局样式
└── app/
    ├── app.ts           # ❤️ 根组件(新版 CLI 去掉了 .component 前缀)
    ├── app.html         # ✅ 新版 CLI 简化了命名,不再是 app.component.html
    ├── app.css          # ✅ 同理
    └── app.config.ts    # 应用的全局配置

有没有注意到少了什么? 没有 app.module.ts 了。

如果你搜 Angular 教程,很多老教程都会先讲 NgModule。但从 Angular 15 开始,官方推出了"独立组件"(standalone components),并在 Angular 17 把它变成了默认模式。新建的项目默认不生成模块文件了。

这是 Angular 团队这几年做的最重要的改变。为什么?因为他们自己也发现------"每次写个小组件还得注册到模块里"这件事太烦人了。Vue 和 React 从来没有这种负担。所以 Angular 决定把这个包袱砍掉。

不过你以后维护老项目还是会遇到 NgModule,它没有被删除。如果你想了解,我最后会简单提一下。

main.ts ------ 启动入口

打开 main.ts,会看到这样的代码:

typescript 复制代码
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app';

bootstrapApplication(AppComponent, appConfig)
  .catch(err => console.error(err));

看到区别了吗?不再是启动一个模块,而是直接启动根组件。 这跟 Vue 的 createApp(App).mount('#app') 和 React 的 createRoot(document.getElementById('root')).render(<App/>) 非常像了。

app.config.ts ------ 全局配置

在 Angular 里,路由、HTTP 拦截器这些全局功能,不是靠"模块"来配置的了,而是通过 app.config.ts

typescript 复制代码
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes)
  ]
};

这里用了一个叫 provide 函数 的模式。需要什么功能,就调用对应的 provideXxx() 函数。是不是有点熟悉?Vue 3 的 app.use(router) 和 React 的各种 Provider 也是类似的路数。

app.ts ------ 根组件(standalone模式)

typescript 复制代码
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';

@Component({
  selector: 'app-root',          // 这个组件在 HTML 中的标签名
  standalone: true,              // ✅ 独立组件
  imports: [RouterOutlet],       // 组件中要用到的其他组件/指令
  templateUrl: './app.html',
  styleUrls: ['./app.css']
})
export class AppComponent {
  title = 'todo-app';
}

注意三个关键点:

  1. standalone: true :这就是它的身份标识。没有 NgModule 包装,组件自己就是完整的。
  2. imports: [] :组件需要用到的其他组件或指令,直接在这里导入。这替代了老版本 NgModule 里的 declarationsimports 的作用。
  3. @Component 装饰器 :用 @ 开头的这种语法叫装饰器(Decorator)。它在告诉 TypeScript:"下面这个类,是一个组件,配置信息在这呢。"

对比一下其他框架的写法:

  • Vue :单文件组件 .vue<template><script><style> 写在一个文件里。
  • React:函数组件,JSX 直接 return HTML 和 JS 混在一起。
  • Angular :逻辑(.ts)、模板(.html)、样式(.css)默认分三个文件,用 @Component 装饰器把它们关联起来。

没有好坏之分。Angular 这么拆分的一个实际好处是:设计师改样式的时候只用动 .css 文件,不会误碰代码逻辑。

补一句:老项目的 NgModule 是什么?

如果你进了个老项目,看到 app.module.ts,别慌。它长这样:

typescript 复制代码
@NgModule({
  declarations: [AppComponent, TodoComponent],
  imports: [BrowserModule],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

你可以把 NgModule 理解成一个"装箱清单"------里面声明"我有哪些组件、用了哪些外部库、根组件是谁"。Angular 以前靠它来组织代码。

但在 standalone 模式下,每个组件就是自己的模块 。你不再需要一个集中清单了,直接在组件里 imports 声明你需要的东西就行。这更符合直觉------跟我用 npm 导包是一个思路。

4. 第一个组件------开始写 Todo

有了项目骨架,我们来创建自己的第一个组件。顺便开始我们的 Todo List 应用。

用 CLI 生成组件

Angular CLI 提供了生成组件的快捷命令:

bash 复制代码
ng generate component todo

简写也可以:

bash 复制代码
ng g c todo

执行完之后,你会在 src/app/ 下看到新文件夹 todo/,里面包含四个文件:

复制代码
app/todo/
├── todo.ts      # 组件逻辑(新版 CLI 去掉了 .component 前缀)
├── todo.html    # 模板
├── todo.css     # 样式
└── todo.spec.ts # 测试(暂时忽略)

注意,CLI 没有去任何文件里注册这个组件。因为在 standalone 模式下,组件自己就是自足的。你直接用就行。

如果你用过老版本的 Angular,一定记得创建完组件还得手动或自动加到 NgModuledeclarations 里。忘加了就报错。这曾是 Angular 被吐槽最多的地方之一。standalone 模式彻底解决了这个问题------跟 Vue、React 一样,import 即用。

组件长什么样?

打开 todo.ts

typescript 复制代码
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-todo',
  standalone: true,           // ✅ 独立组件
  imports: [CommonModule],    // 使用 *ngFor、*ngIf 等内置指令需要导入 CommonModule
  templateUrl: './todo.html',
  styleUrls: ['./todo.css']
})
export class TodoComponent {
  // 这里写组件的逻辑
}

看到 standalone: true 了吗?和 AppComponent 一样。在 Angular 17+ 里,CLI 生成的所有组件默认都是 standalone。

注意 imports 里多了一个 CommonModule。这是因为 standalone 模式下,*ngFor*ngIf 这些内置指令不会自动全局可用 ,你需要从 @angular/common 里导入 CommonModule 才能用它们。

如果你用过老版本 Angular,模块模式下 CommonModule 通常在根模块里一次性导入了,组件里直接写 *ngFor 就行。standalone 模式把这个显式化了------每个组件声明自己需要哪些功能。虽然多写一行 imports,但好处是这个组件依赖什么一目了然,也方便做 tree-shaking。Vue 和 React 没有完全对等的概念,但 React 里你 import { useState } from 'react' 也是每个组件各自导入。

注意 selector 的值是 app-todo。这意味着你可以在其他组件的模板里这样用它:

html 复制代码
<app-todo></app-todo>

把 Todo 组件显示出来

要让 <app-todo> 在页面上显示,需要在 AppComponent 里导入它。修改 app.ts

typescript 复制代码
import { Component } from '@angular/core';
import { TodoComponent } from './todo/todo';  // ← 导入

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [TodoComponent],    // ← 加到 imports 数组
  templateUrl: './app.html',
  styleUrls: ['./app.css']
})
export class AppComponent { }

然后 app.html 删掉默认内容,换成:

html 复制代码
<app-todo></app-todo>

这一步在 Vue 里是 import Todo from './Todo.vue' 然后 <Todo />;在 React 里是 import Todo from './Todo' 然后 <Todo />。Angular standalone 组件的用法已经跟他们基本一致了。 区别只是你需要把导入的组件列到 imports: [] 数组里------多了一步声明,但好处是模板里用了哪些东西一目了然。

写点数据

现在给 Todo 组件加点内容。修改 todo.ts

typescript 复制代码
export class TodoComponent {
  title = '我的待办清单';
  todos = [
    { id: 1, text: '学习 Angular 基础', done: false },
    { id: 2, text: '写一个 Todo 应用', done: true },
    { id: 3, text: '对比 React 和 Vue 的差异', done: false }
  ];
}

然后修改 todo.html

html 复制代码
<h2>{{ title }}</h2>

<ul>
  <li *ngFor="let item of todos">
    {{ item.text }} - {{ item.done ? '已完成' : '未完成' }}
  </li>
</ul>

*ngFor 是 Angular 的循环指令,意思是"遍历 todos 数组,为每个元素生成一个 <li>"。我会在后面专门讲指令,这里先有个印象就好。

对比一下:

  • React 里你会写 todos.map(item => <li key={item.id}>...)`
  • Vue 里你会写 <li v-for="item in todos" :key="item.id">...
  • Angular*ngFor="let item of todos",看起来介于两者之间

保存,浏览器自动刷新(因为 ng serve 支持热更新),你就能看到 Todo 列表了。

组件嵌套的秘密

你现在看到的页面结构是这样的:

复制代码
AppComponent
  └── TodoComponent

AppComponent 是根组件,TodoComponent 是它的子组件。这种树形结构可以一直往下嵌套:

复制代码
AppComponent
  ├── HeaderComponent
  ├── TodoComponent
  │   └── TodoItemComponent
  └── FooterComponent

Angular 应用本质上就是一棵组件树 。根组件(你看到的第一个 <app-root>)是树的根节点,所有其他组件都是它的子节点或孙节点。

关于组件之间怎么"说话"(传数据、通知事件),我们后面会用 @Input@Output 来搞定。现在先消化一下:

组件 = 一段 HTML 模板 + 一个 TypeScript 类 + 一组样式。就这么简单。

5. 本章总结

到目前为止,你现在应该已经:

  1. 理解了 Angular 的"全家桶"定位,以及它和 React、Vue 的核心区别
  2. 装好了 Angular CLI,跑起来了一个新项目
  3. 看懂了项目里几个关键文件是干嘛的
  4. 创建了第一个组件,并且显示出了 Todo 列表

下一章,我们来深入 Angular 最核心的部分------模板和数据绑定,把"写死"的 Todo 变成一个可交互的列表。

相关推荐
烬羽1 小时前
从零理解树与二叉树:用 JS 带你手撕遍历和递归
javascript·数据结构
小徐_23331 小时前
Wot UI 2.1.0 发布:ConfigProvider 全局配置能力升级
前端·uni-app
方白羽1 小时前
Vibe Coding 四个核心阶段
android·前端·app
奶油话梅糖1 小时前
浏览器解析 HTML 头部的底层逻辑:从字节流到资源调度
前端·html
YHL1 小时前
🚀从零理解树与二叉树 —— 概念、实现与遍历
前端·javascript·数据结构
小时前端1 小时前
微前端技术选型深度分析:从概念到实践
前端
十九画生1 小时前
学 JavaScript 数据类型,真正要搞懂的是:变量里存的到底是什么?
javascript
ZengLiangYi1 小时前
测试策略:单元测试 + 集成测试怎么写
javascript·typescript·node.js
wyhwust1 小时前
基于Apifox的接口管理工具
前端