组件的创建与引用
- 创建组件
- 在项目的根目录中,鼠标右键,创建components-test文件夹
- 在新建的components-test文件夹上,鼠标右键点击“新建Component”
- 键入组件的名称之后回车,会自动生成组件对应的4个文件,后缀名分别为.js,.json,.wxml和.wxss
注意:为目录结构清晰需把不同组件放入单独目录中
- 引用组件
- 局部引用:组件只能在当前被引用的页面内使用
- 全局引用:组件可以在每个小程序页面中使用
- 局部引用组件
在页面的.json配置文件中引用组件的方式叫做“局部引用”,示例如下:
{
"usingComponents":{
"my-test":"/components/test/test"
}
}
//在页面.wxml中使用组件
<my-test></my-test>
- 全局引用组件
在app.json全局配置文件中引用组件的方式加全局引用组件,示例如下:
{
"usingComponents":{
"my-test":"/components/test/test"
}
}
//在页面的.wxml文件中使用组件
<my-test></my-test>
- 组件和页面的区别
- 组件的.json文件中需要声明"component":true
- 组件的.js文件中调用的是Component()函数
- 组件的事件处理函数需要定义到methods节点中
自定义组件的样式
- 组件样式隔离
默认情况下组件的样式是隔离的,即组件间样式互不影响,组件样式不影响小程序页面的样式,小程序样式不影响组件的样式。 - 组件样式隔离注意点
- app.wxss中的全局样式对组件无效
- 只有class选择器会有样式隔离效果,id选择器、属性选择器、标签选择器不受样式隔离的影响
- 修改组件的样式隔离选项
- 通过styleIsolation可修改组件的样式隔离特性,用法如下:
Component({
options:{
styleIsolation:'isolated'
}
})
//或者在组件的.json文件中新增如下配置
{
"styleIsolation":"isolated"
}
- 组件styleIsolation配置项
|可选值|默认值|描述|
isolated | 是 | 表示启用样式隔离,在自定义组件内外,使用class指定的样式将不会相互影响 |
apply-shared | 否 | 表示页面wxss样式将影响到自定义组件,但自定义组件wxss中指定的样式不会影响页面 |
shared | 否 | 表示页面wxss样式将影响到自定义组件,自定义组件wxss中指定的wxss中指定的样式也会影响页面和其他设置了apply-shared或shared的自定义组件 |
自定义组件的数据、方法和属性
- data数据
在小程序组件中,用于组件模板渲染的私有数据,需要定义到data节点中。 - methods方法
在小程序中,事件处理函数和自定义方法需要定义到methods节点中,示例如下:
Component({
methods:{
addCount(){
}
}
})
- 小程序组件中,properties是组件的对外属性,用来接收外界传递到组件中的数据,示例如下:
Component({
properties:{
//完整定义可指定默认值
max:{
type:Number,
value:10
},
//简化定义
max:Number
}
})
//在.wxml中使用
<my-test max="10"></my-test>
- data和properties的区别
- properties和data的用法相同,都是可读可写的。
- 两个对象都指向同一个地址,因此输出两个对象应完全相等。
- data更倾向于存储组件的私有数据,properties更倾向于存储外界传递到组件中的数据。
- 使用setData修改properties的值
使用setData为properties中的属性重新赋值,示例如下:
Component({
properties:{max:Number},
methods:{
addCount(){
this.setData({max:this.properties.max+1}) //使用setData修改属性的值
}
}
})
数据监听器
- 什么是数据监听器
用于监听和响应任何属性和数据字段的变化,从而执行特定的操作。类似于vue中的watch,基本语法如下:
Component({
observers:{
'字段A,字段B':function(字段A的新值,字段B的新值){}
}
})
- 监听对象属性的变化
数据监听器支持监听对象中单个或多个属性的变化,示例如下:
Component({
observers:{
'对象.属性a,对象.属性b':function(属性a的新值,属性b的新值){
//触发监听器的三种情况
//为属性a赋值
//为属性b赋值
//为对象赋值
}
}
})
- 监听所有属性的变化
当监听属性太多可通过通配符**来监听对象中所有属性的变化
observers:{
'rgb.**':function(obj){
this.setData({
fullcolor:`${obj.r},${obj.g},${obj.b}`
})
}
}
纯数据字段
- 什么是纯数据字段
指不用于界面渲染的data字段
应用场景:不会展示在界面上,也不会传递给其他组件,仅当前组件内部使用的字段
作用:纯数据字段有助于提升页面更新的性能
- 使用规则
在Component构造器的options节点中,指定pureDataPattern为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段,示例代码如下:
Component({
options:{
pureDataPattern:/^_/
},
data:{
a:true, //普通数据字段
_b:true, //纯数据字段
}
})
组件的生命周期
- 组件的全部生命周期函数
小程序组件可用的全部生命周期如下:
生命周期函数 | 参数 | 描述说明 |
---|---|---|
created | 无 | 在组件实例刚刚被创建时执行 |
attached | 无 | 在组件实例进入页面节点树时执行 |
ready | 无 | 在组件在视图层布局完成后执行 |
moved | 无 | 在组件实例被移动到节点树另一个位置时执行 |
detached | 无 | 在组件实例被从页面节点树移除时执行 |
error | object Error | 每当组件方法抛出错误时执行 |
- 组件主要的生命周期函数
在小程序中最重要的生命周期函数有3个,分别是created、attached、detached。各自特点如下:
- 组件实例刚被创建好的时候,created生命周期函数会被触发:此时不能调用setData,通常只应用于给组件的this添加一些自定义的属性字段。
- 在组件完全初始化完毕、进入页面节点树后,attached生命周期函数会被触发:此时this.data已被初始化完毕,这个生命周期可进行大多数数据初始化工作。
- 在组件离开页面节点树后,detached生命周期函数会被触发:退出页面会触发detached生命周期函数,适合做页面清理工作。
- lifetimes节点
在小程序组件中,生命周期函数可直接定义在Component构造器的第一级参数中,可以在lifetimes字段内进行生明(这是推荐方式优先级最高),示例如下:
Component({
lifetimes:{
attached(){},
detached(){}
}
})
组件所在页面的生命周期
- 什么是组件所在页面的生命周期
自定义组件的行为依赖于页面状态的变化,此时需要用到组件所在页面的生命周期,在自定义组件中,组件所在页面的生命周期有如下3个:
生命周期函数 | 参数 | 描述 |
---|---|---|
show | 无 | 组件所在的页面被展示时执行 |
hide | 无 | 组件所在的页面被隐藏时执行 |
resize | Object Size | 组件所在的页面尺寸变化时执行 |
- pageLifetimes节点
组件所在页面的生命周期函数,需要定义在pageLifetimes节点中,示例如下:
Component({
pageLifetimes:{
show:function(){},
hide:function(){},
resize:function(){}
}
})
小程序的插槽
- 单个插槽
在小程序中,默认每个自定义组件中只允许一个<slot>进行占位,这种个数上的限制叫做单个插槽。 - 启用多个插槽
在小程序的自定义组件中,需要使用多slot插槽时,可以在组件的.js文件中,通过如下方式进行启用。
Component({
options:{
multipleSlots:true
}
})
- 定义多个插槽
可以在组件的.wxml中使用多个slot标签,用不同的name来区分不同的插槽,示例如下:
<view>
<slot name="n1"></slot>
<slot name="n2"></slot>
</view>
- 使用多个插槽
在使用带有多个插槽的自定义组件时,需要使用slot属性来将节点插入到不同的slot中。示例如下:
<component>
<view slot="n1">n1</view>
<view slot="n2">n2</view>
</component>
父子组件之间的通信
- 父子组件之间通信的3种方式
- 属性绑定:用于父组件向子组件的指定属性设置数据,仅能设置JSON兼容的数据
- 事件绑定:用于子组件向父组件传递数据,可以传递任意数据
- 获取组件实例:父组件还可以通过this.selectgComponent()获取子组件实例对象,这样就可以直接访问子组件的任意数据和方法
- 属性绑定
用于实现父向子传值,而且只能传递普通类型的数据,无法将方法传递给子组件,示例如下:
父组件:
data:{
count:0
}
<my-test count="{{count}}"></my-test>
子组件在properties节点中声明对应的属性并使用,示例如下:
properties:{
count:Number
}
//wxml结构
<text>子组件的值为:{{count}}</text>
- 事件绑定
事件绑定用于实现子向父传值,可以传递任何类型的数据。使用步骤如下:
- 在父组件的js中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件。
- 在父组件的wxml中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件。
- 在子组件的js中,通过调用this.triggerEvent('自定义事件名称',{参数对象}),将数据发送到父组件。
- 在父组件的js中,通过e.detail获取到子组件传递过来的数据。
- 事件绑定步骤示例
- 在父组件的js中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件。
syncCount(){
console.log('syncCount')
}
- 在父组件的wxml中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件。
<my-test bind:sync="syncCount"></my-test>
- 在子组件的js中,通过调用this.triggerEvent('自定义事件名称',{参数对象}),将数据发送到父组件。
//wxml结构
<button type="primary" bindtap="addCount">+1</button>
//js代码
methods:{
addCount(){
this.setData({
count:this.properties.count+1
})
this.triggerEvent('sync',{value:this.properties.count})
}
}
- 在父组件的js中,通过e.detail获取到子组件传递过来的数据
syncCount(e){
this.setData({
count:e.detail.value
})
}
- 获取组件实例
可在父组件里调用this.selectComponent("id或class选择器"),获取子组件的实例对象,从而直接访问子组件的任意数据和方法。调用时需要传入一个选择器,例如 this.selectComponent(".my-component")
//wxml结构
<my-test count="{{count}}" bind:sync="syncCount" class="customA"></my-test>
//js代码
getChild(){
const child=this.selectComponent('.customA')
child.setData({count:child.properties.count+1})
child.addCount()
}
自定义组件-behaviors
- 什么是behaviors
用于实现组件间代码共享的特性。 - behaviors的工作方式
每个behaviors可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中。
每个组件可以应用多个behavior,behavior也可以引用其他behavior。
- 创建behavior
调用Behavior(Object object)方法可以创建一个共享的behavior实例对象,供所有的组件使用:
module.exports=Behavior({
properties:{},
data:{username:'zs'},
methods:{},
//其它节点。。。
})
- 导入并使用behavior
在组件中,使用require()方法导入需要的behavior,挂载后即可访问behavior中的数据或方法,示例代码如下:
const myBehavior=require("../../behaviors/my-behavior")
Component({
//将导入的behavior实例对象挂载到behaviors数组节点中,即可生效
behaviors:[myBehavior],
})
- behavior中所有可用的节点
|可用的节点|类型|是否必填|描述|
properties | Object Map | 否 | 同组件的属性 |
data | Object | 否 | 同组件的数据 |
methods | Object | 否 | 同自定义组件的方法 |
behaviors | String Array | 否 | 引入其它的behavior |
created | Function | 否 | 生命周期函数 |
attached | Function | 否 | 生命周期函数 |
ready | Function | 否 | 生命周期函数 |
moved | Function | 否 | 生命周期函数 |
detached | Function | 否 | 生命周期函数 |
- 同名字段的覆盖和组合规则
主要涉及data、properties、methods、生命周期函数。
1.有同名的属性或方法
(1)若组件本身有这个属性或方法,组件的属性或方法会覆盖behavior中的同名属性或方法。
(2)若组件本身没有这个属性或方法,则组件的behaviors字段中定义靠后的behavior的属性或方法会覆盖靠前的同名属性或方法。
(3)在(2)的基础上,若存在嵌套引用behavior的情况,则规则为:父behavior覆盖子behavior中的同名属性或方法。
- 有同名的数据字段data
(1)若同名的数据字段都是对象类型,会进行对象的合并。
(2)其余情况进行数据覆盖,规则为:组件>父behavior>子behavior、靠后的behavior>靠前的behavior。
- 生命周期函数不会相互覆盖,而是在对应触发时机被逐个调用
(1)对于不同的生命周期函数之间,遵循组件生命周期函数的执行顺序。
(2)对于同种生命周期函数,遵循如下规则:
behavior优先于组件执行、子behavior优先于父behavior执行、靠前的behavior优先于靠后的behavior执行。
(3)如果同一个behavior被一个组件多次引用,它定义的生命周期函数只会被执行一次。