组件创建
- Angular:
- 使用TypeScript类来定义组件,通过装饰器
@Component
来标记一个类为组件,并配置元数据,如选择器、模板、样式等。例如:
import { Component } from '@angular/core';
@Component({
selector: 'app - my - component',
templateUrl: './my - component.html',
styleUrls: ['./my - component.css']
})
export class MyComponent {
// 组件逻辑
}
- 模板使用Angular自己的模板语法,支持双向数据绑定、指令等。
- React:
- 既可以使用ES6类来定义组件,也可以使用函数式组件(从React 16.8起,函数式组件可以使用Hook来管理状态和生命周期)。
- 类组件示例:
import React, { Component } from'react';
class MyComponent extends Component {
render() {
return <div>My React Component</div>;
}
}
import React from'react';
const MyComponent = () => {
return <div>My React Component</div>;
};
- 模板使用JSX语法,将HTML和JavaScript融合在一起,更强调JavaScript的逻辑性。
组件通信
- Angular:
- 父子组件通信:父组件通过属性绑定将数据传递给子组件;子组件通过
@Output()
装饰器和EventEmitter
来发射事件给父组件。例如:
- 父组件模板:
<app - child - component [inputData]="parentData" (childEvent)="handleChildEvent($event)"></app - child - component>
- 子组件:
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app - child - component',
templateUrl: './child - component.html'
})
export class ChildComponent {
@Input() inputData;
@Output() childEvent = new EventEmitter();
onButtonClick() {
this.childEvent.emit('Some data from child');
}
}
- 非父子组件通信:可以通过服务(Service)来共享数据,服务是单例的,在整个应用中都可以访问。
- React:
- 父子组件通信:父组件通过属性(props)将数据传递给子组件,子组件不能直接修改props。要向父组件传递数据,子组件需要将父组件传递过来的回调函数作为props,在需要时调用该回调函数并传递数据。例如:
- 父组件:
<ChildComponent data={parentData} handleChildData={this.handleChildData.bind(this)} />
- 子组件:
import React from'react';
const ChildComponent = (props) => {
const handleClick = () => {
props.handleChildData('Some data from child');
};
return <button onClick={handleClick}>Send data to parent</button>;
};
- 非父子组件通信:可以使用Context(从React 16.3起有了更完善的API)来共享数据,但官方建议尽量避免过度使用Context,因为它会使组件之间的关系变得复杂。也可以使用第三方状态管理库如Redux、MobX等。
生命周期管理
- Angular:
- 组件生命周期钩子:有多个生命周期钩子函数,如
ngOnInit
(组件初始化后调用)、ngOnChanges
(当组件的输入属性发生变化时调用)、ngOnDestroy
(组件销毁前调用)等。例如:
import { Component, OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app - my - component',
templateUrl: './my - component.html'
})
export class MyComponent implements OnInit, OnDestroy {
ngOnInit() {
// 初始化逻辑
}
ngOnDestroy() {
// 清理逻辑,如取消订阅等
}
}
- React:
- 类组件生命周期:有
componentDidMount
(组件挂载后调用)、componentDidUpdate
(组件更新后调用)、componentWillUnmount
(组件卸载前调用)等。例如:
import React, { Component } from'react';
class MyComponent extends Component {
componentDidMount() {
// 初始化逻辑
}
componentDidUpdate(prevProps, prevState) {
// 更新逻辑
}
componentWillUnmount() {
// 清理逻辑,如取消订阅等
}
render() {
return <div>My React Component</div>;
}
}
- 函数式组件与Hook:使用
useEffect
Hook来模拟生命周期效果。useEffect
在组件挂载和更新后都会执行,通过传入依赖数组可以控制其执行时机。例如:
import React, { useEffect } from'react';
const MyComponent = () => {
useEffect(() => {
// 类似 componentDidMount 和 componentDidUpdate 的逻辑
return () => {
// 类似 componentWillUnmount 的清理逻辑
};
}, []); // 空数组表示只在挂载时执行一次
return <div>My React Component</div>;
};
对应用开发和维护的影响
- 开发体验:
- Angular:学习曲线较陡,因为其基于TypeScript,有较多的概念如模块、依赖注入、装饰器等。但一旦掌握,代码结构清晰,适合大型企业级应用开发,其双向数据绑定在某些场景下可以减少代码量。
- React:相对容易上手,特别是对于熟悉JavaScript的开发者。JSX语法灵活,函数式编程风格使得代码更简洁,适合快速迭代的项目,但其单向数据流要求开发者更仔细地管理数据传递。
- 维护性:
- Angular:由于其严格的类型系统和结构化的架构,代码在维护时更容易理解和修改,特别是在大型团队中。但如果项目架构设计不合理,修改起来可能会比较复杂。
- React:代码相对灵活,但在大型应用中,如果组件通信和状态管理没有设计好,可能会导致代码难以维护。不过,使用状态管理库可以一定程度上解决这个问题。