前端开发手册——React、Angular 、Vue 三大框架快速入门

285 阅读16分钟

前言

前端web开发中框架必不可缺,它提供结构化方法和组件化编码来简化开发过程,这些工具还可以通过提供可重用组件和抽象复杂任务(如 DOM 操作和状态管理)来帮助提高生产力。这使开发人员可以专注于应用程序逻辑,而不是编写重复的代码。

注意📢📢:本教程适用于已有js基础及node环境 npm的设备

React

特点
  • React是最流行的 JavaScript库,用于构建用户界面。它遵循基于组件的架构。
  • React 利用虚拟 DOM(实际 DOM 的轻量级表示)来高效地更新和渲染组件。
  • React 提倡一种单向数据流,使管理应用程序状态和高效更新 UI 组件变得更加容易。
  • 它提供生命周期方法,允许开发人员在组件生命周期的不同阶段执行操作,例如获取数据、处理事件和相应地更新 UI。

安装

  1. 打开命令终端 输入 npm install -g create-react-app 命令
  2. 运行 npx create-react-app my-react-app 命令 创建 my-react-app 项目
  3. cd my-react-app 项目名称
  4. npm start 会在本地服务器http://localhost:3000启动项目

认识组件

查看下面代码 它将说明如何在react创建一个组件

//父组件
import React from 'react'; 

function Father(props) { 
    return <Child name='Robe' />; 
} 
export default Father;
//子组件
function Child(props) {
  return <h1>你好, {props.name}!</h1>;
}

在上面的代码片段中,我们定义了一个名为Child的组件 该组件接收一个参数name,并使用该参数呈现一条问候消息name

  • 基于组件你可以将应用程序分解为更小的、可重用的组件。
  • 每个组件都可以有自己的状态、道具和生命周期方法,从而更容易管理和维护您的代码库。
  • 组件可以组合和嵌套在一起以创建复杂的用户界面。

虚拟DOM

React 使用虚拟 DOM,它是真实 DOM 的轻量级表示。通过使用虚拟 DOM,React 可以有效地更新和渲染组件,从而产生更快、更流畅的用户界面。

深入研究此代码示例以了解虚拟 DOM 在 React 中的工作方式:

import React from 'react';

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  handleClick() {
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return (
      <div>
        <h1>Count: {this.state.count}</h1>
        <button onClick={() => this.handleClick()}>Increment</button>
      </div>
    );
  }
}

export default Counter;

在上面的代码片段中,我们有一个Counter显示计数值的组件和一个用于递增计数的按钮。每当单击按钮时,该handleClick函数都会使用 更新组件的状态setState,从而触发组件的重新渲染。

  • React 创建了组件结构的虚拟DOM
  • 当状态发生变化时
  • React 会通过diff算法计算之前的虚拟DOM和更新后的虚拟DOM之间的差异
  • 从而重新渲染页面

jsx语法

React 引入了 JSX,这是一种结合了 JavaScript 和类 XML 语法的语法扩展。它允许开发人员在 JavaScript 中编写类似 HTML 的代码,使组件模板更加直观和可读。

import React from 'react';

class Greeting extends React.Component {
  render() {
    const name = 'John Doe';

    return <h1>Hello, {name}!</h1>;
  }
}

export default Greeting;

JSX 提供了几个优点:

  1. 可读性:JSX 类似于 HTML 语法,可以轻松阅读和理解组件 UI 的结构。
  2. 表现力:JSX 允许您以简洁和声明的方式表达复杂的 UI 结构和逻辑。
  3. 组件组合:JSX 支持组合多个组件,允许你构建可重用和模块化的 UI 元素。
  4. JavaScript 的全部功能:由于 JSX 本质上是 JavaScript,因此您可以在 JSX 代码中利用 JavaScript 语言的全部功能,包括变量、函数和控制流语句。

注意📢:jsx是通过Babel等构建工具转化成js的

单向数据流

React 实现了单向数据流,确保数据单向流动。这使修改状态实时更改页面效果变得更加容易。它有助于更好地控制和维护页面的数据流。

在 React 中,数据以单向方式从父组件流向子组件

import React from 'react';

class ParentComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message: 'Hello from Parent',
    };
  }

  render() {
    return (
      <div>
        <ChildComponent message={this.state.message} />
      </div>
    );
  }
}

class ChildComponent extends React.Component {
  render() {
    return <h1>{this.props.message}</h1>;
  }
}

在上面的代码片段中,我们有一个ParentComponent保存名为 的状态变量messageChildComponent然后将此状态作为参数传递给子组件只是渲染 prop 的值message

生命周期

React 提供了生命周期方法,允许开发人员挂接到组件生命周期的不同阶段。这些方法支持获取数据、处理事件和基于特定触发器更新页面等操作。

import React from 'react';

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  componentDidMount() {
    console.log('Component has mounted!');
  }

  componentDidUpdate() {
    console.log('Component has updated!');
  }

  componentWillUnmount() {
    console.log('Component will unmount!');
  }

  handleClick = () => {
    this.setState((prevState) => ({ count: prevState.count + 1 }));
  };

  render() {
    return (
      <div>
        <h1>Count: {this.state.count}</h1>
        <button onClick={this.handleClick}>Increment</button>
      </div>
    );
  }
}

在上面的代码片段中,我们有一个MyComponent基于类的组件,它展示了三个基本的生命周期方法:componentDidMountcomponentDidUpdatecomponentWillUnmount

  • componentDidMount在组件安装到 DOM 中后立即调用。它是从 API 获取数据、设置事件侦听器或执行其他初始化任务的理想场所。
  • componentDidUpdate在更新组件的状态或道具后调用。它使您能够响应更改并根据更新的数据执行其他操作。
  • componentWillUnmount在组件被卸载和销毁之前被调用。它允许您清理任何资源、事件侦听器或订阅以防止内存泄漏。

Hooks

Hooks 2016 年引入的一项新功能(在 React 的 16.8 版本中)

在此之前我们都是类组件,有一个render方法,里面包含呈现页面的jsx 如果想要存储组件的状态,就必须在构造函数里面声明并通过this.setState调用来改变状态,使得阅读体验不佳。在16.8版本之后我们可以写一个函数(更简洁的组合)配合hooks实现各种逻辑与功能。

import { useState } from 'react'

 const Counter = () => {

    const [count, setCount] = useState(0)

    return (
        <div className="App">
            <button onClick={() => setCount(count+1)}>Increment</button>
            <button onClick={() => setCount(count-1)}>Decrement</button>
            <h2>{count}</h2>
        </div>                    
    )
}
export default Counter;

常用hooks

image.png

Angular

Angular 框架,通常称为AngularAngular 2+ ,是由 Google 创建和维护的强大的前端开发平台.2010 年发布的第一个 Angular 版本。AngularJS 引入了双向数据绑定的概念,并因其构建动态和交互式 Web 应用程序的能力而受到欢迎。

安装

1、终端输入 npm i -g @angular/cli

2、ng new 项目名 注意node版本

  • Would you like to add Angular routing ==> 是否要安装 angular路由,Y 回车;
  • Which stylesheet format would you like to use ==> 选择层叠样式表;

3、ng serve 启动项目http://localhost:4200

Angular CLI 提供了各种强大的代码生成命令,有助于简化开发过程。

//此命令创建一个具有指定名称的新组件。它生成组件文件,包括 HTML 模板、CSS 样式、TypeScript 代码和必要的组件测试。
ng generate component component-name 
//此命令生成具有指定名称的新服务。服务用于处理数据、实现业务逻辑和跨组件共享功能。
ng generate service service-name 
//使用此命令创建具有指定名称的新模块。模块通过对相关组件、服务和其他 Angular 元素进行分组来帮助组织和构建 Angular 应用程序。
ng generate module module-name 
//此命令生成具有指定名称的新指令。指令允许您修改 Angular 应用程序中 HTML 元素的行为或外观。
ng generate directive directive-name 
//使用此命令创建具有指定名称的新管道。管道用于转换 Angular 模板中的数据,例如格式化日期、应用自定义过滤器或将输入文本截断或缩短到指定长度。
ng generate pipe pipe-name 

目录讲解
首层目录:
node_modules        第三方依赖包存放目录
e2e                 端到端的测试目录  用来做自动测试的
src                 应用源代码目录  
    app目录              包含应用的组件和模块,我们要写的代码都在这个目录
    assets目录           资源目录,存储静态资源的  比如图片
    environments目录     环境配置。Angular是支持多环境开发的,我们可以在不同的环境下(开发环境,测试环境,生产环境)共用一套代码,主要用来配置环境的
    index.html           整个应用的根html,程序启动就是访问这个页面
    main.ts              整个项目的入口点,Angular通过这个文件来启动项目
    polyfills.ts         主要是用来导入一些必要库,为了让Angular能正常运行在老版本下
    styles.css           主要是放一些全局的样式
    tsconfig.app.json    TypeScript编译器的配置,添加第三方依赖的时候会修改这个文件
    tsconfig.spec.json   不用管
    test.ts              也是自动化测试用的
    typings.d.ts         不用管
angular.json        Angular命令行工具的配置文件。后期可能会去修改它,引一些其他的第三方的包  比如jquery等
karma.conf.js       karma是单元测试的执行器,karma.conf.js是karma的配置文件
package.json        这是一个标准的npm工具的配置文件,这个文件里面列出了该应用程序所使用的第三方依赖包。实际上我们在新建项目的时候,等了半天就是在下载第三方依赖包。下载完成后会放在node_modules这个目录中,后期我们可能会修改这个文件。
protractor.conf.js  也是一个做自动化测试的配置文件
README.md           说明文件
tslint.json         是tslint的配置文件,用来定义TypeScript代码质量检查的规则,不用管它

组件

注意📢:app目录是我们要编写的代码目录

//app.component.ts这个文件是组件
@Component({
  /*组件元数据  Angular会通过这里面的属性来渲染组件并执行逻辑
  *selector就是css选择器,表示这个组件可以通过app-root来调用,index.html中有个<app-root>Loading...</app-root>标签,这个标签用来展示该组件的内容
  *templateUrl  组件的模板,定义了组件的布局和内容
  *styleUrls   该模板引用那个css样式
  * */
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
/*AppComponent本来就是一个普通的typescript类,但是上面的组件元数据装饰器告诉Angular,AppComponent是一个组件,需要把一些元数据附加到这个类上,Angular就会把AppComponent当组件来处理*/
export class AppComponent {
  /*这个类实际上就是该组件的控制器,我们的业务逻辑就是在这个类中编写*/
  title = '学习Angular';
}

模块

Angular 的核心优势之一是其模块化结构,它促进了代码组织、可重用性和可维护性。 在 Angular 中,模块充当对相关组件、服务、指令和其他功能进行分组的容器。每个 Angular 应用程序通常都有一个根模块,称为AppModule,用作应用程序的入口点

//app.module.ts 是模板
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { } 

在这个例子中,我们有一个AppModule用装NgModule饰器装饰的类。在装饰器内部,我们为模块定义元数据。

declarations数组列出了属于该模块的所有组件、指令和管道。在这里,我们声明了一个组件AppComponent

imports数组指定此模块所依赖的其他模块。在这种情况下,我们将导入BrowserModule,它提供了在 Web 浏览器中运行 Angular 应用程序的基本功能。

providers数组用于提供此模块中的组件所需的任何服务或依赖项。

bootstrap数组表示应用程序的根组件,应用程序启动时会实例化。在这里,我们AppComponent指定为引导程序组件。

自己定义组件

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

@Component({
  selector: 'app-example',
  template: `
    <h1>Welcome to the Example Component!</h1>
    <p>This is the content of the component.</p>
  `
})
export class ExampleComponent {
  // Component logic goes here
}

在这个例子中,我们有一个ExampleComponent用装饰器装饰的类@Component。在装饰器内部,我们为组件定义元数据。

selector属性指定用于呈现组件的 HTML 选择器。在本例中,选择器是app-example,这意味着组件将按照<app-example></app-example>HTML 中的方式呈现。

template属性定义组件的视图或模板。它包含将在使用组件时呈现的 HTML 标记。在这个例子中,我们有一个简单的标题和段落。

ExampleComponent表示组件的逻辑和行为。在这里,您可以定义属性和方法,并处理与组件相关的事件。

服务

服务用于跨多个组件共享数据、逻辑和功能。它们封装了可重用的业务逻辑、数据访问以及与外部 API 的通信。服务可以注入到组件或其他服务中,从而实现关注点的明确分离并提高代码的可重用性。

Angular 中的服务可以比作使房屋运转顺畅的帮手或助手。想象一下你住在一所房子里,有不同的人帮助你完成特定的任务。例如,您可能需要清洁服务来保持房屋整洁,需要水管工来解决任何与水有关的问题,以及需要电工来处理电气问题。

例如,您可以拥有从外部源(如服务器或数据库)检索和存储数据的数据服务。多个组件可以使用此数据服务来获取和更新数据,从而确保整个应用程序的一致性。

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

@Injectable()
export class DataService {
  getData(): string {
    return 'This is data retrieved from the DataService!';
  }
}

在这个例子中,我们有一个DataService的类用@Injectable装饰器。这个装饰器将类标记为可注入服务,允许它被注入到其他组件或服务中。

在类内部DataService,我们定义了一个getData返回字符串的方法。此方法可用于从 API 获取数据、执行计算或与数据检索相关的任何其他逻辑。

Angular 中的服务负责处理数据、业务逻辑和其他跨组件的共享功能。它们促进了代码的可重用性、关注点分离,并提供了一种在应用程序中集中常见操作和数据访问的方法。

指令

if指令它根据特定条件有条件地显示或隐藏元素。这可用于根据用户输入或应用程序状态动态显示内容。 使用高亮指令为特定的HTML元素添加特殊效果,使其以不同的颜色或动画突出显示。该指令可用于突出显示网页上的重要信息或交互元素。

属性型指令

  1. NgClass : 动态添加和删除一组css类
  2. NgStyle : 动态添加和删除一组内联样式
  3. NgModel : 将数据的双向绑定添加到HTML表单元素上
import { Component } from '@angular/core';

@Component({
  selector: 'app-zc',
  template: `
  <div [ngClass]="isShow ? 'ng_ClassSty' : 'ng_classSty'">{{title}}</div>

  `,
  styleUrls: ['./zc.component.less']
})
export class ZcComponent {
  public title = 'hello Zc';
  public isShow = false;
}

结构类型指令

  1. NgFor : 重复渲染某节点
  2. NgIf : 从模板中创建或销毁子视图,通俗说是控制组件或者元素的显示和隐藏
  3. NgSwitch: 类似于js中的switch的逻辑,也是按照满足固定的条件显示某些模板/视图
// 在js中,如果需要渲染列表,我们是需要手动遍历数据,然后动态生成元素,这样才能实现列表的渲染
// 在angular中,我们仅仅需要使用NgFor这个语法糖就可以实现数据的循环展示
import { Component } from '@angular/core';

@Component({
  selector: 'app-hello-world',
  template: `
  <ul>
    <li *ngFor="let item of arr">{{item}}</li>
  </ul>
  `,
  styles: []
})

export class HelloWorldComponent {
  public arr = ['A','B','C','D'];
}
// 假如有个需求:
// 说是用户身份是’backend‘的就可以看到上述的循环列表;其他的用户都不能看到,在Angular中改怎么实现呢?
import { Component } from '@angular/core';

@Component({
  selector: 'app-hello-world',
  template: `
  <ul *ngIf="userRole === 'backend'">
    <li *ngFor="let subject of studySubjects;  let i=index">{{ i+1 }} - {{ subject }}</li>
  </ul>
  `,
  styles: []
})

export class HelloWorldComponent {
  public userRole='backend'; // 只要userRole的值不是backend,那么上述的列表就不会展示
}

自定义指令

import { Directive, ElementRef, HostListener } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
  constructor(private elementRef: ElementRef) {}

  @HostListener('mouseenter')
  onMouseEnter() {
    this.highlight('yellow');
  }

  @HostListener('mouseleave')
  onMouseLeave() {
    this.highlight(null);
  }

  private highlight(color: string | null) {
    this.elementRef.nativeElement.style.backgroundColor = color;
  }
}

在页面上使用appHighlight

<div appHighlight>
  This is a highlighted element. Move your mouse over it to see the effect!
</div>

在此示例中,我们创建一个名为appHighlight的指令,使用 selector 应用于 HTML 元素[appHighlight]

当用户悬停在元素上时,onMouseEnter事件侦听器被触发,它调用方法highlight将元素的背景颜色设置为黄色。

同样,当用户将鼠标移离元素时,onMouseLeave事件侦听器被触发,并通过将背景颜色设置回默认值来消除高亮效果。

通过将appHighlight指令附加到 HTML 元素,我们可以动态地控制它的外观和行为。这演示了 Angular 中指令的概念,您可以在其中定义可应用于 HTML 元素以增强其功能和视觉表示的自定义行为或指令。

生命周期

要使用哪个钩子函数,就先引入
import {OnInit} from ...
再实现
export class 组件名 implements Onint...
再使用
ngOnInit(){
....
}

ngOnChanges() 当angular(重新)设置数据绑定输入属性时相应。该方法接受当前和上一属性值的simpleChanges对象,当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在ngOnInit()之前。

ngOnInit() 在angular第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。

在第一轮ngOnchanges()完成之后调用,只调用一次

ngDoCheck() 检测,并在发生angular无法或不愿意自己检测的变化时作出反应,在每个angular变更检测周期中调用,在ngOnChanges()和ngOnInit()之后

ngAfterContentInit() 当把内容投影进组件之后调用,第一次ngDoCheck()之后调用,只调用一次,只适用于组件

ngAfterContentChecked() 每次完成被投影组件内容的变更检测之后调用,ngAfterContentInit()和每次ngDoCheck()之后调用,只适用于组件

ngAfterViewInit() 初始化完组件视图及其子视图之后调用。第一次ngAfterContentChecked()之后调用,只调用一次,只适合组件。

ngAfterViewChecked() 每次做完组件视图和子视图的变更检测之后调用。ngAfterViewInit()和每次ngAfterContentChecked()之后调用,只适合组件

ngOnDestroy 当angular每次销毁指令/组件之前调用并清扫,在这里反订阅可观察和分离事件处理器,以防内存泄漏

Vue

Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架。它旨在平易近人、用途广泛,并且易于集成到现有项目中。无论您是初学者还是经验丰富的开发人员,Vue.js 都提供了平滑的学习曲线和灵活的架构,使其成为 Web 应用程序开发的热门选择。

未完待续......