组件定义方式
- Angular:
- 使用TypeScript类来定义组件。通过装饰器
@Component
来标识一个类为组件,并在装饰器中配置组件的元数据,如selector
(用于在HTML中选择该组件)、templateUrl
(组件模板文件路径)、styleUrls
(组件样式文件路径)等。例如:
import { Component } from '@angular/core';
@Component({
selector: 'app - my - component',
templateUrl: './my - component.html',
styleUrls: ['./my - component.css']
})
export class MyComponent {
// 组件逻辑代码
}
- 模板使用Angular的模板语法,支持插值、指令等,与组件类紧密结合。
- Vue:
- 有多种方式定义组件。可以使用对象字面量形式,也可以使用单文件组件(
.vue
文件)。在单文件组件中,<template>
标签定义组件的模板结构,<script>
标签定义组件的逻辑(通常是JavaScript或TypeScript),<style>
标签定义组件的样式。例如:
<template>
<div>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello, Vue!'
};
}
};
</script>
<style scoped>
div {
color: blue;
}
</style>
数据传递机制
- Angular:
- 父子组件:父组件通过绑定属性向子组件传递数据。在子组件类中使用
@Input()
装饰器来接收父组件传递的数据。例如,父组件模板中:<app - child - component [inputValue]="parentData"></app - child - component>
,子组件类中:
import { Component, Input } from '@angular/core';
@Component({
selector: 'app - child - component',
templateUrl: './child - component.html'
})
export class ChildComponent {
@Input() inputValue;
}
- 子父组件:子组件通过
@Output()
装饰器和EventEmitter
来向父组件发送事件和数据。子组件触发事件,父组件在模板中监听该事件并处理数据。例如,子组件类中:
import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app - child - component',
templateUrl: './child - component.html'
})
export class ChildComponent {
@Output() dataToParent = new EventEmitter();
sendData() {
this.dataToParent.emit('Some data from child');
}
}
- 父组件模板中:
<app - child - component (dataToParent)="handleChildData($event)"></app - child - component>
。
- 非父子组件:通常使用服务(Service)来共享数据。服务是一个单例对象,不同组件可以注入同一个服务实例,通过服务来传递和共享数据。
- Vue:
- 父子组件:父组件通过属性绑定向子组件传递数据。子组件在
props
选项中声明要接收的属性。例如,父组件模板中:<child - component :input - value="parentData"></child - component>
,子组件中:
export default {
props: ['inputValue'],
// 组件逻辑
}
- 子父组件:子组件通过
$emit
方法触发自定义事件并传递数据给父组件。父组件在模板中监听该自定义事件。例如,子组件中:this.$emit('send - data', 'Some data from child');
,父组件模板中:<child - component @send - data="handleChildData"></child - component>
。
- 非父子组件:对于简单场景可以使用
Vue.prototype
挂载一个全局事件总线来实现数据传递;对于复杂状态管理,Vuex是常用的解决方案,它通过集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
生命周期钩子函数使用特点
- Angular:
- 创建阶段:
ngOnInit
:在组件初始化完成后调用,此时组件的输入属性已绑定,可以在此进行数据初始化、订阅Observable等操作。
ngOnChanges
:当组件的输入属性发生变化时调用,首次绑定也会调用。可以在此处理输入属性变化带来的逻辑。
- 更新阶段:
ngDoCheck
:每次变更检测运行时调用,可在此实现自定义的变更检测逻辑,但频繁调用可能影响性能,使用需谨慎。
ngAfterContentInit
:当组件内容(<ng - content>
投影的内容)初始化完成后调用。
ngAfterContentChecked
:每次组件内容检查完成后调用。
ngAfterViewInit
:当组件视图(包括子视图)初始化完成后调用,可在此操作DOM。
ngAfterViewChecked
:每次组件视图检查完成后调用。
- 销毁阶段:
ngOnDestroy
:在组件销毁前调用,可在此取消订阅、清理定时器等操作,防止内存泄漏。
- Vue:
- 创建阶段:
beforeCreate
:实例刚被创建,数据观测和事件机制未初始化,此时无法访问数据和方法。
created
:实例创建完成,数据观测和事件机制已就绪,可以访问数据和方法,可在此进行数据获取等操作。
- 挂载阶段:
beforeMount
:在挂载开始之前被调用,此时模板已编译,但尚未挂载到DOM,$el属性还不存在。
mounted
:实例被挂载后调用,此时可以访问挂载的DOM元素,可进行DOM操作等。
- 更新阶段:
beforeUpdate
:数据更新时调用,此时DOM还未更新,可在更新前访问现有DOM状态。
updated
:数据更新且DOM更新完成后调用,可在此操作更新后的DOM。
- 销毁阶段:
beforeDestroy
:实例销毁前调用,实例仍然可用,可在此清理定时器、解绑事件等。
destroyed
:实例销毁后调用,所有指令已解绑,事件监听器已移除,子实例也已销毁。