微信小程序组件生命周期
-
onLoad, 生命周期函数--监听页面加载
-
onReady 生命周期函数--监听页面初次渲染完成
-
onShow 监听页面显示
-
onHide -监听页面隐藏
-
onUnload 监听页面卸载
-
onPullDownRefresh 监听用户下拉动作
-
onReachBottom 页面上拉触底事件的处理函数
-
onShareAppMessage 用户点击右上角分享
组件生命周期函数
组件所在页面的生命周期
一:组件
1:创建
2:引用
1):局部引用
2):全局引用
3:组件和页面区别
4:组件的样式隔离
1):默认的情况组件和页面的,组件与组件样式的是隔离的
2): app.wss 全局样式对组件中的样式 无效;所以必须用 @import "/app.wxss"引入
3):只有class选择器会有样式隔离效果,id选择器,属性选择器,标签选择器不受隔离效果(推荐用class)
4):针对性修改隔离效果方法 stylelsolation (2种方法):
5:组件中 事件处理和自定义事件 【为了代码分风格,自定义事件前面加__】
6:组件中properties 属性
7:组件中的 data和properties 的区别
8:组件中使用setData修改properties值
9:组件中数据监听器
1)变量监听
2)对象属性监听
案例:
3)监听所有属性(**通配符)
10:纯数字字段(不渲染到xwl)
1):使用规则
2):纯数字字段改变数据监听案例(上面对象属性监听案例改造)
11:组件中生命周期函数
1):主要三个生命周期函数 create 、attached、detached
12:lifetimes 节点(新版和旧版对比,推荐用新)
13:组件所在页面的生命周期
1):定义
2)pageLifetimes 节点
lifetimes【组件中的生命周期】 和 pageLifetimes【组件所在页面的生命周期】 区别
Component({
data: {
animationTimer: null,
isPageShowing: true
},
// 1. 组件自身的生命周期
lifetimes: {
attached: function() {
console.log('【组件】已挂载到页面');
this.startAnimation(); // 页面初始是显示的,所以启动动画
},
detached: function() {
console.log('【组件】被销毁');
this.stopAnimation(); // 组件销毁时,彻底停止动画
}
},
// 2. 组件所在页面的生命周期 (核心!)
pageLifetimes: {
show: function() {
console.log('【页面】展示 - 组件感知到了');
},
hide: function() {
console.log('【页面】隐藏 - 组件感知到了');
},
resize: function(size) {
console.log('【页面】尺寸变化', size);
}
},
methods: {
}
})
案例:页面一进来随机默认一个颜色
14:组件中的插槽
1):定义
2)单个插槽
3)多个插槽
4)定义多个插槽
1. 基本用法
在微信小程序中,slot 的基本用法是在子组件中定义一个插槽,父组件可以在使用子组件时向插槽中传递内容。
子组件 (child-component.wxml):
<view class="container">
<view>子组件的内容</view>
<slot></slot> <!-- 这里是插槽,父组件的内容会插入到这里 -->
</view>
父组件 (parent-component.wxml):
<view>
<child-component>
<view>这是插入到子组件中的内容。</view>
</child-component>
</view>
在这个例子中,<view>这是插入到子组件中的内容。</view> 会被插入到子组件的 <slot></slot> 位置。
2. 具名插槽 (Named Slots)
微信小程序也支持具名插槽,允许你在子组件中定义多个插槽,并通过名字来指定内容插入到哪个插槽中。
子组件 (child-component.wxml):
<view class="container">
<view>子组件的内容</view>
<slot name="header"></slot> <!-- 具名插槽 -->
<slot></slot> <!-- 默认插槽 -->
<slot name="footer"></slot> <!-- 具名插槽 -->
</view>
父组件 (parent-component.wxml):
<view>
<child-component>
<view slot="header">这是头部内容</view>
<view>这是默认插槽的内容。</view>
<view slot="footer">这是底部内容</view>
</child-component>
</view>
在这个例子中,slot="header" 和 slot="footer" 分别指定了内容插入到具名插槽 header 和 footer 中,而没有指定 slot 的内容会插入到默认插槽中。
3. 作用域插槽 (Scoped Slots)
微信小程序目前不支持像 Vue 那样的作用域插槽(即子组件向父组件传递数据)。不过,你可以通过其他方式实现类似的功能,例如通过 properties 或 events 来传递数据。
4. 默认内容
你可以在 slot 中定义默认内容,当父组件没有提供内容时,默认内容会显示。
子组件 (child-component.wxml):
<view class="container">
<view>子组件的内容</view>
<slot>这是默认内容</slot>
</view>
父组件 (parent-component.wxml):
<view>
<child-component></child-component> <!-- 显示默认内容 -->
<child-component>
<view>这是自定义内容</view>
</child-component> <!-- 显示自定义内容 -->
</view>
15:子组件的之间通信
1):总结三种方法
2):性绑定(只能传普通数据给子组件)
3):子组件向父组件传送数据 this.triggerEvent()
案例:
4):使用selectComponent获取组件实例
16:behaviors 各个组件共享代码
1):定义
2):方式
3):创建
4):导入
5):可用的节点
6):同名覆盖规则
参考:
developers.weixin.qq.com/miniprogram…
在微信小程序中,behaviors 是一种用于在多个组件之间共享代码的机制。通过 behaviors,你可以将一些通用的逻辑、数据、方法等提取出来,然后在多个组件中复用。这样可以减少代码重复,提高代码的可维护性和可复用性。
1. 什么是 Behaviors?
behaviors 类似于面向对象编程中的“混入”(Mixin),它允许你将一些通用的功能封装到一个独立的模块中,然后在多个组件中引入和使用。每个 behavior 可以包含以下内容:
- 数据 (
data): 共享的数据字段。 - 方法 (
methods): 共享的方法。 - 生命周期函数: 共享的生命周期逻辑。
- 其他配置: 如
properties、observers等。
2. 创建 Behavior
behavior 是一个普通的 JavaScript 文件,通常以 .js 为后缀。你可以通过 Behavior() 函数来定义一个 behavior。
my-behavior.js:
module.exports = Behavior({
data: {
sharedData: '这是共享的数据'
},
methods: {
sharedMethod() {
console.log('这是共享的方法');
}
},
created() {
console.log('Behavior 创建了');
},
attached() {
console.log('Behavior 附加了');
}
});
在这个例子中,我们定义了一个 behavior,它包含了一些共享的数据和方法。
3. 在组件中使用 Behavior
在组件中使用 behavior 时,只需要在组件的 behaviors 字段中引入即可。
组件 (my-component.js):
const myBehavior = require('./my-behavior.js');
Component({
behaviors: [myBehavior], // 引入 behavior
data: {
localData: '这是组件本地的数据'
},
methods: {
localMethod() {
console.log('这是组件本地的方法');
}
},
created() {
console.log('组件创建了');
},
attached() {
console.log('组件附加了');
}
});
在这个例子中,my-component 组件引入了 my-behavior,因此它可以访问 my-behavior 中定义的 sharedData 和 sharedMethod。
4. Behavior 的生命周期
behavior 也有自己的生命周期函数,这些生命周期函数会在组件的生命周期中被调用。behavior 的生命周期函数与组件的生命周期函数是合并执行的,执行顺序如下:
behavior的created- 组件的
created behavior的attached- 组件的
attached
5. Behavior 的冲突处理
如果 behavior 和组件中有同名的字段或方法,微信小程序会按照一定的规则进行合并:
- 数据 (
data): 同名的数据字段会进行合并,如果冲突,组件中的数据会覆盖behavior中的数据。 - 方法 (
methods): 同名的方法会进行合并,如果冲突,组件中的方法会覆盖behavior中的方法。 - 生命周期函数: 同名的生命周期函数会合并执行,
behavior的生命周期函数先执行,组件的生命周期函数后执行。
6. 多个 Behavior 的合并
一个组件可以引入多个 behavior,这些 behavior 会按照数组顺序进行合并。如果多个 behavior 中有同名的字段或方法,后面的 behavior 会覆盖前面的 behavior。
组件 (my-component.js):
const behaviorA = require('./behavior-a.js');
const behaviorB = require('./behavior-b.js');
Component({
behaviors: [behaviorA, behaviorB], // 引入多个 behavior
data: {
localData: '这是组件本地的数据'
},
methods: {
localMethod() {
console.log('这是组件本地的方法');
}
}
});
7. 示例
假设我们有两个 behavior,分别用于处理用户信息和日志记录:
user-behavior.js:
module.exports = Behavior({
data: {
userInfo: null
},
methods: {
getUserInfo() {
wx.getUserInfo({
success: (res) => {
this.setData({
userInfo: res.userInfo
});
}
});
}
}
});
log-behavior.js:
module.exports = Behavior({
methods: {
log(message) {
console.log(`[LOG]: ${message}`);
}
}
});
然后在组件中使用这两个 behavior:
my-component.js:
const userBehavior = require('./user-behavior.js');
const logBehavior = require('./log-behavior.js');
Component({
behaviors: [userBehavior, logBehavior],
methods: {
onLoad() {
this.getUserInfo(); // 来自 userBehavior
this.log('组件加载了'); // 来自 logBehavior
}
}
});
8. 总结
behaviors是微信小程序中用于组件间代码复用的机制。- 你可以将通用的逻辑、数据、方法等提取到
behavior中,然后在多个组件中共享使用。 behavior的生命周期函数与组件的生命周期函数合并执行。- 如果
behavior和组件中有同名的字段或方法,组件中的会覆盖behavior中的。 - 一个组件可以引入多个
behavior,它们会按照数组顺序进行合并。
通过使用 behaviors,你可以更好地组织和管理微信小程序中的代码,减少重复代码,提高开发效率。
16:组件总结
小程序的优化
- 分包加载:将非核心功能拆分成子包,优化首屏加载。
- 分包预下载:在用户可能使用前,提前下载好分包。
- 图片优化:压缩、选对格式(WebP)、使用 CDN 和懒加载。
- 数据/文件缓存:合理使用本地存储,减少网络请求。
- 代码精简:删除无用代码,使用自定义组件。
- 高效
setData:避免频繁调用和大数据传输。 - 善用 WXS:处理高频交互,减少通信损耗。
1、分包加载和分包预下载
“首次只加载主包,分包按需加载+预加载”的策略
主包(1个)+分包(12)
- 整个小程序所有分包大小不超过 20M。
- 单个分包/主包大小不能超过 2M。
分包就是将一个小程序按照不同的维度(如功能、页面)划分成多个子包。启动时只下载主包,进入某个特定功能时再按需下载对应的分包。
- 主包:包含小程序启动页面(tabBar 页面)以及这些页面所需的所有相关资源(JS, WXML, WXSS, 图片等)。
- 分包:包含与主包功能相对独立,且非 tabBar 页面的功能模块。
核心思想:按需加载
-
编译时分离:在开发者上传代码时,微信开发者工具会根据
app.json中的subpackages和preloadRule配置, 将代码和资源明确地划分到主包和各个分包中,并生成对应的包信息。 -
运行时按需加载:
- 用户首次打开小程序,只会下载主包(通常 < 2M)。
- 当用户通过导航(如点击按钮)要访问某个分包的页面时,小程序运行时环境会检查该页面所在的包是否已被下载。
- 如果未下载,则会阻塞当前导航行为,显示一个全局的“正在加载...”提示,同时从 CDN 下载对应的分包。
- 分包下载并注入完成后,才会正式跳转到目标页面,后续再访问该分包内的任何页面都无需重新加载。
3. 分包的配置
在 app.json 中进行配置:
{
"pages": [
"pages/index/index",
"pages/logs/logs"
],
"subpackages": [
{
"root": "packageA",
"name": "packA", // 分包别名,用于分包预下载
"pages": [
"pages/cat/cat",
"pages/dog/dog"
]
},
{
"root": "packageB",
"pages": [
"pages/apple/apple",
"pages/banana/banana"
]
}
],
"preloadRule": {
"pages/index/index": {
"network": "all",
"packages": ["packageA"] // 当进入 pages/index/index 时,预下载 packageA
}
}
}
4. 分包预下载原理
为了进一步提升用户体验,避免用户在点击时等待分包下载,小程序提供了分包预下载机制。
- 原理:在进入某个页面(通常是主包页面)后,在空闲时间 quietly 下载指定的分包。这样当用户真正需要进入该分包时,包已经准备就绪,可以实现秒开。
- 配置:通过
app.json的preloadRule字段配置。如上面的例子,当用户进入首页 (pages/index/index) 后,会自动在后台预下载packageA。
总结分包原理:通过将非核心功能代码从主包剥离,利用“首次只加载主包,分包按需加载+预加载”的策略,极大地优化了小程序的启动性能。
2、图片优化
-
压缩图片:使用工具(如 TinyPNG, Squoosh)对图片进行无损或有损压缩。
-
选择合适的格式:
- WebP:同等质量下体积比 PNG/JPG 小很多。小程序已支持,但需考虑低版本兼容性(可做兼容判断,不支持则 fallback 到 JPG)。
- SVG:适用于图标、LOGO 等矢量图。
-
使用 CDN 和合适尺寸:
- 不要将大量高分辨率图片打包到代码包里,应上传至 CDN。
- 根据显示区域的大小,从 CDN 请求对应尺寸的图片。例如,一个需要显示 200x200 像素的头像,就不要请求 1000x1000 的原图。
-
懒加载:使用小程序原生的
lazy-load属性,让屏幕外的图片在需要时才加载。
<image src="{{imgUrl}}" lazy-load mode="widthFix"></image>
3. 缓存策略
合理利用缓存可以减少网络请求,提升二次访问速度。
-
数据缓存 (
wx.setStorage,wx.getStorage):- 缓存不常变化但频繁使用的数据,如用户信息、城市列表、配置信息等。
- 为缓存设置合理的过期时间,或提供手动刷新机制。
-
文件缓存 (
wx.saveFile,wx.getFileSystemManager):- 对于较大的静态文件(如 PDF、视频),可以下载到本地缓存,避免重复下载。
-
请求缓存:
- 对于相同的 API 请求,可以在内存中做一个短期缓存(例如 5 秒),避免短时间内重复请求。
3. 代码层面的优化
清理无用代码和资源:定期检查并删除未使用的 JS 函数、WXML 组件、WXSS 样式和图片。
-
减少
setData的调用频率和数据量:setData是视图层和逻辑层的通信,频繁调用或传输大量数据(如巨大的数组)会引起性能问题。- 只 set 发生变化的数据,而不是整个 data 对象。
- 对
列表进行分页避免一次性 set 大量数据。
-
使用自定义组件:将复杂的页面拆分成独立的自定义组件,可以实现更好的代码复用和隔离,组件的更新不会影响页面其他部分。
-
使用 WXS 处理交互:对于需要高频交互的场景(如滚动、触摸),使用 WXS 可以在视图层直接处理,避免逻辑层和视图层的频繁通信带来的延迟。