小程序组件可用的全部生命周期如下表所示
生命周期函数 | 参数 | 描述说明 |
---|---|---|
created | 无 | 在组件实例刚刚被创建时执行 |
attached | 无 | 在组件实例进入页面节点树时执行 |
ready | 无 | 在组件在视图层布局完成后执行 |
moved | 无 | 在组件实例被移动到节点树另一个位置时执行 |
detached | 无 | 在组件实例被从页面节点树移除时执行 |
error Object | Error | 每当组件方法抛出错误时执行 |
在小程序组件中,最重要的生命周期函数有 3 个,分别是 created 、 attached 、 detached 。它们各自的特点如下:
组件实例 刚被创建 好的时候,created 生命周期函数会被触发 此时还不能调用 setData通常在这个生命周期函数中,只应该用于给组件的 this 添加一些自定义的属性字段
在组件 完全初始化完毕、进入页面节点树后 , attached 生命周期函数会被触发此时, this.data 已被初始化完毕这个生命周期很有用,绝大多数初始化的工作可以在这个时机进行(例如发请求获取初始数据)
在组件 离开页面节点树后 , detached 生命周期函数会被触发退出一个页面时,会触发页面内每个自定义组件的 detached 生命周期函数此时适合做一些清理性质的工作
/**
* 组件的初始数据
*/
data: {
_rgb:{ // rgb 的颜色值对象
r:0,
g:0,
b:
},
fullColor: '0, 0, 0' //根据rgb对象的三个属性,动态计算fullColor 的值
},
})
生命周期函数 参数 描述
show 无 组件所在的页面被展示时执行
hide 无 组件所在的页面被隐藏时执行
resize Object Size 组件所在的页面尺寸变化时执行
在小程序组件中,生命周期函数可以直接定义在 Component 构造器的第一级参数中,可以在 lifetimes字段内进行声明( 这是推荐的方式,其优先级最高 )。示例代码如下:
有时, 自定义组件的行为依赖于页面状态的变化 ,此时就需要用到 组件所在页面的生命周期 。例如:每 当触发页面的 show 生命周期函数的时候,我们希望能够重新生成一个随机的 RGB 颜色值。在自定义组件中,组件所在页面的生命周期函数有如下 3 个,分别是:
// components/test3/test3.js
Component({
//旧式的定义方式
created() {
console.log('created'); //在组建实例进入页面节点树时执行
},
attached(){
console.log('attached'); //在组件实例被从页面节点树移除时执行
},
// 推荐用法
lifetimes:{
created() {
console.log('created~'); //在组建实例进入页面节点树时执行
},
attached(){
console.log('attached~');//在组件实例被从页面节点树移除时执行
},
}
})
组件所在页面的生命周期函数,需要定义在 pageLifetimes 节点中,示例代码如下
// components/test3/test3.js
Component({
pageLifetimes:{
show(){
console.log('show');
},
hide(){
console.log('hide');
},
resize(){
console.log('resize');
}
}
})
// components/test3/test3.js
Component({
/**
* 组件的方法列表
*/
methods: {
changeR(){ //修改 rgb 对象上 r属性的值
this.setData({
'_rgb.r':this.data._rgb.r + 5 > 255? 255 : this.data._rgb.r
+ 5
在自定义组件的 wxml 结构中,可以提供一个 节点(插槽),用于 承载组件使用者提供的 wxml结构。
changeG(){ // 修改rgb对象上r属性的值
this.setData({
'_rgb.g':this.data._rgb.g + 5 >255 ?255 :this.data._rgb.g +
})
},
changeB(){//修改 rgb对象上b属性的值
this.setData({
'_rgb.b':this.data._rgb.b + 5 > 255? 255 :this.data._rgb.b
+
})
},
_randomColor() {
this.setData({
_rgb:{
r: Math.floor(Math.random() * 256),
g: Math.floor(Math.random() * 256),
b: Math.floor(Math.random() * 256)
}
})
}
},
pageLifetimes:{
show(){
console.log('show');
this._randomColor()
}
}
})
在小程序中,默认每个自定义组件中只允许使用一个 进行占位,这种个数上的限制叫做单个插槽。
在components 中新建一个test4文件夹 在文件中新建component
在app.json usingComponents中 添加组件目录
"usingComponents": {
"my-test1":"/components/test/test",
"my-test2":"/components/test2/test2",
"my-test3":"/components/test3/test3",
"my-test4":"/components/test4/test4"
},
在组件.wxml中定义结构
<view>
<view>
这里是组件的内部结构
view>
<slot>slot>
view>
在页面的.wxml定义结构:
<my-test4>
<view>
这是通过插槽填充的内容
view>my-test4>
可以在组件的 .wxml 中使用多个 标签,以不同的 name 来区分不同的插槽。在组件.wxml中 加上一个slot标签 为每个slot标签定义name属性值
// components/test4/test4.js
Component({
options: {
multipleSlots: true //在组件定义时选型中启用多slot支持
},
properties: {/* ... */},
data: {/* ... */},
methods: {/* ... */ }
})
<view>
<slot name="before">slot>
<view> 这里是组件的内部结构 view>
<slot name="after">slot>
view>
用于父组件向子组件的指定属性设置数据,仅能设置 JSON 兼容的数据
用于子组件向父组件传递数据,可以传递任意数据
父组件还可以通过 this.selectComponent() 获取子组件实例对象可以直接访问子组件的任意数据和方法
属性绑定用于实现父向子传值,而且只能传递普通类型的数据,无法将方法传递给子组件
在home.js中定义数据
<my-test4>
<view slot="after">这是通过插槽填充的内容view>
<view slot="before">~~~~~~~view>
my-test4>
// 父组件的data节点
data: {
count:0
}
在components 中新建一个test5文件夹 在文件中新建component
在app.json usingComponents中 添加组件目录:
在home首页中使用一下这个组件
子组件在 properties 节点中声明对应的属性,并使用实现子组件按钮自增加一的效果
// 父组件的.wxml结构
<my-test3 count="{{count}}"> my-test3>
<view>-----view>
<view>父组件中,count值为:{{count}}view>
"usingComponents": {
"my-test1":"/components/test/test",
"my-test2":"/components/test2/test2",
"my-test3":"/components/test3/test3",
"my-test4":"/components/test4/test4",
"my-test5":"/components/test5/test5"
},
<my-test5 count="{{count}}">my-test5>
<view>~~~~~~~~~~~view>
<view>父组件中,count值是:{{count}}view>
// components/test5/test5.js
Component({
/**
* 组件的属性列表
*/
properties: {
count:Number
事件绑定 用于实现子 向父传值 ,可以传递任何类型的数据。使用步骤如下:
步骤 1 :在父组件的 js 中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件。
在 父组件 的 js 中,定义一个函数,这个函数 即将 通过自定义事件的形式,传递给子组件
在 父组件 的 wxml 中,通过自定义事件的形式,将步骤 1 中定义的函数引用,传递给子组件
在子组件的 js 中,通过调用 this.triggerEvent (‘自定义事件名称’, { /* 参数对象 */ }) ,将数据发送到父组件
在 父组件 的 js 中,通过 e.detail 获取到子组件传递过来的数据
步骤 2 :在 父组件 的 wxml 中(home.wxml),通过 自定义事件 的形式,将步骤 1 中定义的函数引用,
传递给子组件。
使用bind:自定义事件名称 (推荐:结构清晰)
或在bind后面直接写上自定义事件名称
步骤 3 :在子组件的 js 中,通过调用 this.triggerEvent(‘自定义事件名称’, { /* 参数对象 */ }) ,将数据发子组件的.wxml结构(test5.wxml)
子组件的js代码
//在父组件中定义sysncCount方法
// 将来,这个方法会被传递给子组件,供子组件进行调用
Page({
/**
* 页面的初始数据
*/
data: {
count:0
},
sysncCount(){
console.log('sysncCount');
},
<my-test5 count="{{count}}" bind:sync="sysncCount">my-test5>
<view>子组件中,count值是:{{count}}view>
<button type="primary" bindtap="addCount">+1button>
// components/test5/test5.js
Component({
methods: {
addCount(){
this.setData({
count:this.properties.count + 1
})
// 触发自定义事件,将数值同步给父组件
this.triggerEvent('sync',{value:this.properties.count})
}
}
})
在父组件的 js 中,通过 e.detail 获取到子组件传递过来的数据。
可在父组件里调用 this.selectComponent(“id或class选择器”) ,获取子组件的实例对象,从而直接访问子组件的任意数据和方法。调用时需要传入一个选择器,例如 this.selectComponent(“.my- component”)。
home.wxml定义结构
sysncCount(e){
// console.log('sysncCount');
// console.log(e);
// console.log(e.detail.value);
this.setData({
count: e.detail.value
})
},
<my-test5 count="{{count}}" bind:sync="sysncCount" class="customA" id='cA'>
my-test5>
<view>~~~~~~~~~~~view>
<view>父组件中,count值是:{{count}}view>
<button bindtap="getChild">获取子组件的实例对象button>
// pages/home/home.js
Page({
/**
* 页面的初始数据
*/
data: {
count:0
},
sysncCount(e){
// console.log('sysncCount');
// console.log(e);
// console.log(e.detail.value);
this.setData({
count: e.detail.value
})
},
getChild(){
//切记不能传递标签选择器否自返回的是null
const child = this.selectComponent('.customA')
// console.log(child);
// 调用子组件的 setData方法
// child.setData({
// count:child.properties.count +1 //注意此处只能用child不能用this
// })
child.addCount()//调用子组件的addCount方法
},
})