自定义组件
生命周期
- created: 不能调用setData。这个生命周期只应该给组件this添加一些自定义属性字段
- attached: data被初始化,大多数初始化在这里完成
- detached: 组件离开
数据
数据是组件的私有数据,可以用于模板渲染,但是在data中不能使用外部数据,比如引入图片路径,data将读取不到
访问数据
this.data.dataName
属性
属性是由外部传入
Component({
properties:{
userName:String,
innerText:{
type: String,
value: "文字"
}
}
})
访问属性
this.properties.propName
// OR
this.data.propName
属性类型校验和默认值
- 使用type可以校验属性的类型,类型包括: String、Number、Boolean、Object、Array、null(任意类型) 。
- 使用value可以设置属性的默认值。
使用属性还是数据
一般不直接使用属性里面的值,尤其是属性里面的值会变动时。这个时候我们监听属性,获取到属性的值并设置为data的值
// 绑定内部数据
<text>{{myNumber}}</text>
properties: {
// 对外数据
numOrigin:{
type:Number,
value:10,
observer:function(newV,oldV,changedPath){
let val = newV<10?`0${newV}`:newV;
this.setData({
// 修改对内数据
myNumber:val
})
}
}
},
data: {
// 对内数据
myNumber:10
},
// 调用组件
<number-area numOrigin="{{8}}"/>
数据和属性监听
监听属性
properties:{
userName:{
type:String,
value:"默认名字",
observer:function(newV, oldV, changePath){
}
}
}
监听数据
// 参数中的name对应user.name
user.name:funcion(name){
name = this.data.user.name;
}
// 监听所有子数据的变动
'user.**':function(user){
user = this.data.user
}
父子组件通信
父组件传值给子组件
调用组件时在组件上使用prop-data-name即可给父组件传值,在子组件中声明properties即可接收。
// 在父页面中
<view>
<test-component prop-a="{{dataA}}" prop-b="{{dataB}}"></test-component>
</view>
子组件传值给父组件
在子组件中使用triggerEvent(事件名,值)
的方式即可将数据传递给父组件
this.triggerEvent('emitPerson', { name: '李明',age:'123' });
父组件中使用bind:事件名
或者bind事件名
的方式绑定事件(后者更常用),使用e.detail
获取到传出的值。
// 方式一
<carousel bind:emitPerson="getPerson" />
getPerson:function(e){
console.log(e.detail);
}
// 方式二
<carousel bind:emitPerson="getPerson" />
getPerson:function(e){
console.log(e.detail);
}
父组件调用子组件的事件
调用子组件时,在组件上声明一个id属性,通过selectComponent("#id").方法
调用
<carousel content="{{mydata}}" bind:emitPerson="getPerson" myTitle="测试标题测试标题" id="banner"/>
this.selectComponent("#banner").clear();
插槽
单个插槽
如果编写的组件中只有一个插槽,我们可以直接在组件使用使用slot
。
// test组件
<view>
组件的名字叫做<slot></slot>
</view>
// 调用test组件
<test-com>测试组件</test-com>
多个插槽
如果编写的组件中有多个插槽, 则需要在组件js中声明multipleSlots: true
Component({
options:{
multipleSlots: true
}
})
示例slot
// 在组件中test-component
<view>
<slot name="header"></slot>
<view>页面内容</view>
<slot name="footer"></slot>
</view>
// 引用组件时
<test-component>
<view slot="header">页头</view>
<view slot="footer">页脚</view>
</test-component>
混用 behaviors
组件的复用,当多个组件有相同的properties、data和methods甚至相同的生命周期,我们可以使用behaviors.
behaviors是一个数组,小程序会自动合并相同的属性。如果有多个behaviors,且存在相同的属性,那么会按照前后顺序覆盖。
比如以下:
// beh.js 混用
const testBeh = Behavior({
data:{
name:1
}
})
export {testBeh}
// 调用
import {testBeh} from './testBeh';
Component({
behaviors:[testBeh]
})
样式
注意事项
- 组件中尽量使用class,不使用id选择器、属性选择器和标签名选择器
- 不使用后代选择器和子元素选择器
- 样式会从组件外继承到组件内
- 要使组件外的样式不影响组件,在js文件的options属性声明
stylesolation:'isolated'
传入外部样式
// 组件引入页
<test-component my-class="test-class"></test-component>
Component({
externalClasses:['my-class']
})
// wxss样式
.test-class{
color: red;
}
组件关系 relations
relations: {
// 该组件的父组件为cell-group
'../cell-group/index': {
type: 'parent'
}
},
relations: {
// 该组件的子组件为cell
'../cell/index': {
type: 'child',
linked () {
this._updateIsLastCell();
},
linkChanged () {
this._updateIsLastCell();
},
unlinked () {
this._updateIsLastCell();
}
}
},