前言
前端web开发中框架必不可缺,它提供结构化方法和组件化编码来简化开发过程,这些工具还可以通过提供可重用组件和抽象复杂任务(如 DOM 操作和状态管理)来帮助提高生产力。这使开发人员可以专注于应用程序逻辑,而不是编写重复的代码。
注意📢📢:本教程适用于已有js基础及node环境 npm的设备
React
特点
- React是最流行的 JavaScript库,用于构建用户界面。它遵循基于组件的架构。
- React 利用虚拟 DOM(实际 DOM 的轻量级表示)来高效地更新和渲染组件。
- React 提倡一种单向数据流,使管理应用程序状态和高效更新 UI 组件变得更加容易。
- 它提供生命周期方法,允许开发人员在组件生命周期的不同阶段执行操作,例如获取数据、处理事件和相应地更新 UI。
安装
- 打开命令终端 输入
npm install -g create-react-app命令 - 运行
npx create-react-app my-react-app命令 创建 my-react-app 项目 cd my-react-app项目名称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 提供了几个优点:
- 可读性:JSX 类似于 HTML 语法,可以轻松阅读和理解组件 UI 的结构。
- 表现力:JSX 允许您以简洁和声明的方式表达复杂的 UI 结构和逻辑。
- 组件组合:JSX 支持组合多个组件,允许你构建可重用和模块化的 UI 元素。
- 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保存名为 的状态变量message,ChildComponent然后将此状态作为参数传递给子组件只是渲染 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基于类的组件,它展示了三个基本的生命周期方法:componentDidMount、componentDidUpdate和componentWillUnmount。
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
Angular
Angular 框架,通常称为Angular或Angular 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元素添加特殊效果,使其以不同的颜色或动画突出显示。该指令可用于突出显示网页上的重要信息或交互元素。
属性型指令
NgClass: 动态添加和删除一组css类NgStyle: 动态添加和删除一组内联样式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;
}
结构类型指令
NgFor: 重复渲染某节点NgIf: 从模板中创建或销毁子视图,通俗说是控制组件或者元素的显示和隐藏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 应用程序开发的热门选择。