Component 和 Page 是微信小程序中两种不同的基础类,它们在功能、生命周期和使用场景上有所区别。
1. 定义和用途
Page:用于定义一个页面。每个小程序的页面都是一个Page对象,通常用于表示应用中的一个界面。一个小程序可以包含多个页面,页面之间可以通过路由进行跳转。Component:用于定义一个组件。组件是可以在多个页面中复用的 UI 单元,通常用于封装一些功能性较强、可复用的界面元素,例如按钮、表单、列表项等。
2. 生命周期
生命周期是指在 Page 或 Component 的实例创建、渲染、销毁过程中触发的一系列钩子函数。尽管 Component 和 Page 都有生命周期,但它们的钩子和触发时机有所不同。
Page 的生命周期:
Page 主要有以下几个生命周期函数:
onLoad():页面加载时触发,通常用于获取初始化数据。onShow():页面显示时触发,每次页面从后台返回前台时会触发。onReady():页面初次渲染完成时触发,视图已加载完毕。onHide():页面隐藏时触发,通常用于暂停或保存当前页面状态。onUnload():页面卸载时触发,通常用于清理资源,如取消定时器、清理事件监听等。
Component 的生命周期:
Component 主要有以下生命周期函数:
created():组件实例化时触发,组件的数据还未绑定到视图中。attached():组件被添加到页面节点树时触发,通常在此方法中进行视图相关的操作。ready():组件渲染完成后触发,此时组件的视图已经完成,可以访问并操作 DOM 节点。detached():组件从页面节点树中移除时触发,通常用于清理事件或定时器等资源。
3. 数据和事件处理
Page中的数据管理:页面的数据通过data属性定义,页面中的数据可以直接通过this.setData()方法进行更新,页面的逻辑和数据紧密结合。Component中的数据管理:组件的数据也通过data属性定义,组件的数据和视图更新同样通过this.setData()更新,但是组件的数据是局部的,作用范围仅限于该组件内部。组件还可以通过properties和methods来与父页面进行数据交互和事件传递。
4. 通信方式
Page和Component之间的通信:- 页面可以通过
customComponent标签嵌套组件,将数据传递给组件,组件也可以通过triggerEvent向页面发送事件。 - 组件通过
properties接收外部传递的数据,通过events发送事件给外部页面。
例如,父页面传递数据给子组件:
html<!-- Page --> <custom-component prop1="value1" prop2="value2"></custom-component>javascript// Component Component({ properties: { prop1: String, prop2: String }, methods: { handleEvent() { this.triggerEvent('customEvent', { message: 'Hello' }); } } });- 页面可以通过
5. 结构和功能
Page:每个页面都会有一个对应的.wxml、.wxss、.js和.json文件。页面控制的是整个界面,通常包含多个组件和视图元素。每个页面有自己的数据、逻辑和生命周期管理。Component:组件则是页面中的一部分,通常只有.wxml、.wxss和.js文件。组件的职责是封装某一特定功能或视图片段,组件通过properties接收数据,通过methods定义功能。
6. 路径和页面栈
Page:每个页面都有一个独立的路径,可以通过wx.navigateTo、wx.redirectTo等 API 进行页面跳转。页面之间有独立的栈结构,跳转的页面会被推入栈中。Component:组件没有独立的路径,它是页面的一部分,通常嵌套在页面的wxml中。组件是页面的 UI 组成部分,而不是独立的导航单元。
7. 使用场景
Page:用于构建应用中的单独页面。每个页面通常会包含多个组件、视图和页面逻辑,例如首页、详情页、设置页等。Component:用于封装页面中的小模块,提升代码的复用性。比如一个列表项、一个按钮、一个表单等,多个页面可以共享同一个组件。
总结对比
| 特性 | Page | Component |
|---|---|---|
| 用途 | 定义小程序页面,表示一个界面 | 定义可复用的组件,封装页面中的某个功能或UI |
| 生命周期 | onLoad、onShow、onReady、onUnload等 | created、attached、ready、detached等 |
| 数据管理 | 通过 data 和 this.setData() 更新数据 | 通过 data、properties 和 methods 管理数据 |
| 通信方式 | 通过 setData、getCurrentPages 访问其他页面 | 通过 properties 接收数据,通过 triggerEvent 发送事件 |
| 是否有独立路径 | 每个页面都有独立的路径 | 组件没有独立路径,嵌套在页面中 |
| 使用场景 | 页面之间的跳转、显示单独界面 | 页面中的UI组件,封装某一特定功能或视图 |
何时使用 Page 和 Component?
- 使用
Page:当你需要创建一个独立的页面时,使用Page。每个页面代表一个完整的视图结构,通常会包含多个组件和页面逻辑。 - 使用
Component:当你需要封装可复用的UI组件,或对某一功能模块进行封装时,使用Component。组件能够在多个页面之间复用,提升开发效率和代码可维护性。
// pages/index/index.js
Page({
data: {
message: 'Hello World',
count: 0
},
// 页面加载时触发
onLoad: function(options) {
console.log('页面加载', options);
},
// 页面显示/切入前台时触发
onShow: function() {
console.log('页面显示');
},
// 页面初次渲染完成时触发
onReady: function() {
console.log('页面初次渲染完成');
},
// 页面隐藏/切入后台时触发
onHide: function() {
console.log('页面隐藏');
},
// 页面卸载时触发
onUnload: function() {
console.log('页面卸载');
},
// 自定义方法
increment: function() {
this.setData({
count: this.data.count + 1
});
}
});// components/my-component/my-component.js
Component({
properties: {
// 组件属性
myProperty: {
type: String,
value: ''
}
},
data: {
// 组件内部数据
internalData: 'Internal Data'
},
methods: {
// 自定义方法
customMethod: function() {
console.log('自定义方法被调用');
}
},
observers: {
// 属性观察者
'myProperty': function(newVal, oldVal) {
console.log('myProperty changed', newVal, oldVal);
}
},
// 组件的生命周期函数
lifetimes: {
attached: function() {
console.log('组件attached');
},
ready: function() {
console.log('组件ready');
},
detached: function() {
console.log('组件detached');
}
}
});