[WeChat Mini Program] Life cycle, slots and communication between components

insert image description here

1. Component life cycle

1.1 All life cycle functions of components

All life cycles available for applet components are shown in the table below

life cycle function parameter Description
created none Executed when the component instance has just been created
attached none Executed when the component instance enters the page node tree
ready none Executed after the component has been laid out in the view layer
moved none Executed when a component instance is moved to another location in the node tree
detached none Executed when a component instance is removed from the page node tree
error Object Error Executed whenever a component method throws an error

1.2 Main lifecycle functions of components

In the applet component, there are three most important life cycle functions, namely created, attached and detached. Their respective characteristics are as follows:

  1. When the component instance is just created, the created lifecycle function will be triggered. At this time, setData cannot be called. Usually, in this lifecycle function, it should only be used to add some custom attribute fields to the this of the component.

  2. After the component is fully initialized and enters the page node tree, the attached life cycle function will be triggered. At this time, this.data has been initialized. This life cycle is very useful, and most of the initialization work can be performed at this time (such as sending a request get initial data)

  3. After the component leaves the page node tree, the detached lifecycle function will be triggered. When exiting a page, the detached lifecycle function of each custom component in the page will be triggered. At this time, it is suitable to do some cleaning work.

/**
* 组件的初始数据
*/
data: {
    
    
_rgb:{
    
     // rgb 的颜色值对象
r:0,
g:0,
b:
},
fullColor: '0, 0, 0' //根据rgb对象的三个属性,动态计算fullColor 的值
},
})

Life cycle function parameter description
show Executed when the page without components is displayed
hide Executed when the page without components is hidden
resize Object Size Executed when the size of the page where the component is located changes

1.3 lifetime node

In the applet component, the lifecycle function can be directly defined in the first-level parameter of the Component constructor, and can be declared in the lifetimes field (this is the recommended way, and its priority is the highest). The sample code is as follows:

2. The life cycle of the page where the component is located

2.1 What is the life cycle of the page where the component is located

Sometimes, the behavior of the custom component depends on the change of the state of the page. At this time, the life cycle of the page where the component is located needs to be used. For example: whenever the show lifecycle function of the page is triggered, we want to be able to regenerate a random RGB color value. In a custom component, there are three life cycle functions of the page where the component is located, namely:

// components/test3/test3.js
Component({
    
    
//旧式的定义方式
created() {
    
    
console.log('created'); //在组建实例进入页面节点树时执行
},
attached(){
    
    
console.log('attached'); //在组件实例被从页面节点树移除时执行
},
// 推荐用法
lifetimes:{
    
    
created() {
    
    
console.log('created~'); //在组建实例进入页面节点树时执行
},
attached(){
    
    
console.log('attached~');//在组件实例被从页面节点树移除时执行
},
}
})

2.2 pageLifetimes node

The life cycle function of the page where the component is located needs to be defined in the pageLifetimes node, the sample code is as follows

2.3 Generate random RGB color values

// 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

3. Slot

3.1 What is a slot

In the wxml structure of the custom component, a node (slot) can be provided to carry the wxml structure provided by the component user.

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()
}
}
})

3.2 Single slot

In the applet, only one placeholder is allowed in each custom component by default, and this limit on the number is called a single slot.

Create a new test4 folder in components Create a new component in the file

Add the component directory in app.json usingComponents

"usingComponents": {
    
    
"my-test1":"/components/test/test",
"my-test2":"/components/test2/test2",
"my-test3":"/components/test3/test3",
"my-test4":"/components/test4/test4"
},

Define structure in component.wxml

<!--components/test4/test4.wxml-->
<view>
<view>
这里是组件的内部结构
</view>
<slot></slot>
</view>

Define the structure in the page's .wxml:

<!--pages/home/home.wxml-->
<my-test4>
<view>
这是通过插槽填充的内容
</view></my-test4>

3.3 Define multiple slots

Multiple tags can be used in the component's .wxml to distinguish different slots with different names. Add a slot tag to the component.wxml to define the name attribute value for each slot tag

// components/test4/test4.js
Component({
    
    
options: {
    
    
multipleSlots: true //在组件定义时选型中启用多slot支持
},
properties: {
    
    /* ... */},
data: {
    
    /* ... */},
methods: {
    
    /* ... */ }
})
<!--components/test4/test4.wxml-->
<view>
<slot name="before"></slot>
<view> 这里是组件的内部结构 </view>
<slot name="after"></slot>
</view>

4. Communication between parent and child components

4.1 Three ways of communication between parent and child components

1. Attribute binding

It is used to set data from the parent component to the specified property of the child component, only JSON-compatible data can be set

2. Event binding

It is used for child components to pass data to parent components, and any data can be passed

3. Get the component instance

The parent component can also get the child component instance object through this.selectComponent() and can directly access any data and methods of the child component

4.2 Property Binding

Attribute binding is used to pass values ​​from parent to child, and can only pass common types of data, and methods cannot be passed to child components.
Define data in home.js

<my-test4>
<!-- 这部分内容将被放置在组件 <slot name="after">的位置上 -->
<view slot="after">这是通过插槽填充的内容</view>
<!-- 这部分内容将被放置在组件 <slot name="before">的位置上 -->
<view slot="before">~~~~~~~</view>
</my-test4>
// 父组件的data节点
data: {
    
    
count:0
}
Define the structure in home.js

Create a new test5 folder in components Create a new component in the file

Add the component directory in app.json usingComponents:

Use this component on the home page

The subcomponent declares the corresponding property in the properties node, and uses the effect of self-incrementing the subcomponent button

// 父组件的.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

4.3 Event Binding

Event binding is used to pass values ​​from child to parent, and any type of data can be passed. The steps to use are as follows:

Step 1 : In the js of the parent component, define a function that will be passed to the child component in the form of a custom event.

  1. In the js of the parent component, define a function that will be passed to the child component in the form of a custom event

  2. In the wxml of the parent component, pass the function reference defined in step 1 to the child component in the form of a custom event

  3. In the js of the child component, send data to the parent component by calling this.triggerEvent ('custom event name', { /* parameter object */ })

  4. In the js of the parent component, the data passed by the child component is obtained through e.detail

Step 2 : In the wxml of the parent component (home.wxml), refer to the function defined in step 1 in the form of a custom event,

passed to child components.

Use bind: custom event name (recommended: clear structure)

Or write the custom event name directly after bind

Step 3 : In the js of the subcomponent, send the data to the .wxml structure of the subcomponent (test5.wxml) by calling this.triggerEvent('custom event name', { /* parameter object */ })

The js code of the child component

//在父组件中定义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">+1</button>
// components/test5/test5.js
Component({
    
    
methods: {
    
    
addCount(){
    
    
this.setData({
    
    
count:this.properties.count + 1
})
// 触发自定义事件,将数值同步给父组件
this.triggerEvent('sync',{
    
    value:this.properties.count})
}
}
})

In the js of the parent component, the data passed by the child component is obtained through e.detail.

4.4 Get component instance

You can call this.selectComponent("id or class selector") in the parent component to get the instance object of the child component, so as to directly access any data and methods of the child component. A selector needs to be passed in when calling, for example this.selectComponent(“.my-component”).
home.wxml defines the structure

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方法
},
})

Guess you like

Origin blog.csdn.net/2301_76710810/article/details/130247116