一.组件模板
1、组件模版
组件模板的写法与页面模板相同。组件模板与组件数据结合后生成的节点树,将被插入到组件的引用位置上。
在组件模板中可以提供一个 <slot> 节点,用于承载组件引用时提供的子节点。
<!-- 组件模板 --> <view class="wrapper"> <view>这里是组件的内部节点</view> <slot></slot> </view> <!-- 引用组件的页面模板 --> <view> <component-tag-name> <!-- 这部分内容将被放置在组件 <slot> 的位置上 --> <view>这里是插入到组件slot中的内容</view> </component-tag-name> </view>
2、模板数据绑定
<!-- 引用组件的页面模板 --> <view> <component-tag-name prop-a="{{dataFieldA}}" prop-b="{{dataFieldB}}"> <!-- 这部分内容将被放置在组件 <slot> 的位置上 --> <view>这里是插入到组件slot中的内容</view> </component-tag-name> </view>
组件页面
Js设置
properties: { propA: String }
wxml页面调用
{{propA}}
3、组件wxml的slot
在组件的wxml中可以包含 slot 节点,用于承载组件使用者提供的wxml结构。
默认情况下,一个组件的wxml中只能有一个slot。需要使用多slot时,可以在组件js中声明启用。
Component({ options: { multipleSlots: true // 在组件定义时的选项中启用多slot支持 }, properties: { /* ... */ }, methods: { /* ... */ } })
此时,可以在这个组件的wxml中使用多个slot,以不同的 name 来区分。
<!-- 组件模板 --> <view class="wrapper"> <slot name="before"></slot> <view>这里是组件的内部细节</view> <slot name="after"></slot> </view>
使用时,用 slot 属性来将节点插入到不同的slot上。
<!-- 引用组件的页面模板 --> <view> <component-tag-name> <!-- 这部分内容将被放置在组件 <slot name="before"> 的位置上 --> <view slot="before">这里是插入到组件slot name="before"中的内容</view> <!-- 这部分内容将被放置在组件 <slot name="after"> 的位置上 --> <view slot="after">这里是插入到组件slot name="after"中的内容</view> </component-tag-name> </view>
二.组件样式
组件对应 wxss 文件的样式,只对组件wxml内的节点生效。编写组件样式时,需要注意以下几点:
- 组件和引用组件的页面不能使用id选择器(#a)、属性选择器([a])和标签名选择器,请改用class选择器。
- 组件和引用组件的页面中使用后代选择器(.a .b)在一些极端情况下会有非预期的表现,如遇,请避免使用。
- 子元素选择器(.a>.b)只能用于 view 组件与其子节点之间,用于其他组件可能导致非预期的情况。
- 继承样式,如 font 、 color ,会从组件外继承到组件内。
- 除继承样式外, app.wxss 中的样式、组件所在页面的的样式对自定义组件无效。
1、外部样式类
/* 组件 custom-component.js */
Component({ externalClasses: ['my-class'] })
<!– 组件 custom-component.wxml –>
<custom-component class="my-class">
这段文本的颜色由组件外的 class 决定</custom-component>
2、使组件接受全局样式
/* 组件 custom-component.js */
Component({ options: { addGlobalClass: true, } })
<!– 组件 custom-component.wxml –>
<text class="red-text">
这段文本的颜色由 `app.wxss` 和页面 `wxss` 中的样式定义来决定</text>
三.Component构造器
1、 定义段
定义段 | 类型 | 是否必填 | 描述 | 最低版本 |
properties | Object Map | 否 | 组件的对外属性,是属性名到属性设置的映射表,属性设置中可包含三个字段, type表示属性类型、 value 表示属性初始值、 observer 表示属性值被更改时的响应函数 | |
data | Object | 否 | 组件的内部数据,和 properties 一同用于组件的模板渲染 | |
observers | Object | 否 | 组件数据字段监听器,用于监听 properties 和 data 的变化,参见 数据监听器 | 2.6.1 |
methods | Object | 否 | 组件的方法,包括事件响应函数和任意的自定义方法,关于事件响应函数的使用,参见 组件事件 | |
behaviors | String Array | 否 | 类似于mixins和traits的组件间代码复用机制,参见 behaviors | |
created | Function | 否 | 组件生命周期函数,在组件实例刚刚被创建时执行,注意此时不能调用 setData ,参见 组件生命周期 | |
attached | Function | 否 | 组件生命周期函数,在组件实例进入页面节点树时执行,参见 组件生命周期 | |
ready | Function | 否 | 组件生命周期函数,在组件布局完成后执行,参见 组件生命周期 | |
moved | Function | 否 | 组件生命周期函数,在组件实例被移动到节点树另一个位置时执行,参见 组件生命周期 | |
detached | Function | 否 | 组件生命周期函数,在组件实例被从页面节点树移除时执行,参见 组件生命周期 | |
relations | Object | 否 | 组件间关系定义,参见 组件间关系 | |
externalClasses | String Array | 否 | 组件接受的外部样式类,参见 外部样式类 | |
options | Object Map | 否 | 一些选项(文档中介绍相关特性时会涉及具体的选项设置,这里暂不列举) | |
lifetimes | Object | 否 | 组件生命周期声明对象,参见 组件生命周期 | 2.2.3 |
pageLifetimes | Object | 否 | 组件所在页面的生命周期声明对象,支持页面的 show 、 hide 等生命周期,参见 组件生命周期 | 2.2.3 |
definitionFilter | Function | 否 | 定义段过滤器,用于自定义组件扩展,参见 自定义组件扩展 | 2.2.3 |
2、 属性
属性名 | 类型 | 描述 |
is | String | 组件的文件路径 |
id | String | 节点id |
dataset | String | 节点dataset |
data | Object | 组件数据,包括内部数据和属性值 |
properties | Object | 组件数据,包括内部数据和属性值(与 data 一致) |
方法名 | 参数 | 描述 |
setData | Object newData | 设置data并执行视图层渲染 |
hasBehavior | Object behavior | 检查组件是否具有 behavior (检查时会递归检查被直接或间接引入的所有behavior) |
triggerEvent | String name, Object detail, Object options | 触发事件,参见 组件事件 |
createSelectorQuery | 创建一个 SelectorQuery 对象,选择器选取范围为这个组件实例内 | |
createIntersectionObserver | 创建一个 IntersectionObserver 对象,选择器选取范围为这个组件实例内 | |
selectComponent | String selector | 使用选择器选择组件实例节点,返回匹配到的第一个组件实例对象(会被 wx://component-export 影响) |
selectAllComponents | String selector | 使用选择器选择组件实例节点,返回匹配到的全部组件实例对象组成的数组 |
getRelationNodes | String relationKey | 获取这个关系所对应的所有关联节点,参见 组件间关系 |
groupSetData | Function callback | 立刻执行 callback ,其中的多个 setData 之间不会触发界面绘制(只有某些特殊场景中需要,如用于在不同组件同时 setData 时进行界面绘制同步) |
getTabBar | 无 | 返回当前页面的 custom-tab-bar 的组件实例,详见自定义 tabBar |
3、 方法
方法名 | 参数 | 描述 |
setData | Object newData | 设置data并执行视图层渲染 |
hasBehavior | Object behavior | 检查组件是否具有 behavior (检查时会递归检查被直接或间接引入的所有behavior) |
triggerEvent | String name, Object detail, Object options | 触发事件,参见 组件事件 |
createSelectorQuery | 创建一个 SelectorQuery 对象,选择器选取范围为这个组件实例内 | |
createIntersectionObserver | 创建一个 IntersectionObserver 对象,选择器选取范围为这个组件实例内 | |
selectComponent | String selector | 使用选择器选择组件实例节点,返回匹配到的第一个组件实例对象(会被 wx://component-export 影响) |
selectAllComponents | String selector | 使用选择器选择组件实例节点,返回匹配到的全部组件实例对象组成的数组 |
getRelationNodes | String relationKey | 获取这个关系所对应的所有关联节点,参见 组件间关系 |
groupSetData | Function callback | 立刻执行 callback ,其中的多个 setData 之间不会触发界面绘制(只有某些特殊场景中需要,如用于在不同组件同时 setData 时进行界面绘制同步) |
getTabBar | 无 | 返回当前页面的 custom-tab-bar 的组件实例,详见自定义 tabBar |
注意:在 properties 定义段中,属性名采用驼峰写法(propertyName);在 wxml 中,指定属性值时则对应使用连字符写法(component-tag-name property-name=”attr value”),应用于数据绑定时采用驼峰写法(attr=”{{propertyName}}”)。
4、 构造页面
组件的属性可以用于接收页面的参数,如访问页面 /pages/index/index?paramA=123¶mB=xyz ,如果声明有属性 paramA 或 paramB ,则它们会被赋值为 123 或 xyz 。
页面的生命周期方法(即 on 开头的方法),应写在 methods 定义段中。
代码示例:
{ "usingComponents": {} }
Component({ properties: { paramA: Number, paramB: String, }, methods: { onLoad() { this.data.paramA // 页面参数 paramA 的值 this.data.paramB // 页面参数 paramB 的值 } } })
五.组件间通信与事件
1、 组件间通信
组件间的基本通信方式有以下几种。
- WXML 数据绑定:用于父组件向子组件的指定属性设置数据,仅能设置 JSON 兼容数据(自基础库版本 2.0.9 开始,还可以在数据中包含函数)。具体在 组件模板和样式 章节中介绍。
- 事件:用于子组件向父组件传递数据,可以传递任意数据。
- 如果以上两种方式不足以满足需要,父组件还可以通过 this.selectComponent 方法获取子组件实例对象,这样就可以直接访问组件的任意数据和方法。
2、 监听事件
事件系统是组件间通信的主要方式之一。自定义组件可以触发任意的事件,引用组件的页面可以监听这些事件。
监听自定义组件事件的方法与监听基础组件事件的方法完全一致:
代码示例:
<!– 当自定义组件触发“myevent”事件时,调用“onMyEvent”方法 –>
<component-tag-name bindmyevent="onMyEvent" />
<!– 或者可以写成 –>
<component-tag-name bind:myevent="onMyEvent" />
Page({ onMyEvent(e) { e.detail // 自定义组件触发事件时提供的detail对象 } })
3、 触发事件
自定义组件触发事件时,需要使用 triggerEvent 方法,指定事件名、detail对象和事件选项:
代码示例:
<!– 在自定义组件中 –>
<button bindtap=”onTap”>点击这个按钮将触发“myevent”事件</button>
Component({ properties: {}, methods: { onTap() { const myEventDetail = {} // detail对象,提供给事件监听函数 const myEventOption = {} // 触发事件的选项 this.triggerEvent('myevent', myEventDetail, myEventOption) } } })
4、 组件间使用数据监听器
有时,在一些数据字段被 setData 设置时,需要执行一些操作。
例如, this.data.sum 永远是 this.data.numberA 与 this.data.numberB 的和。此时,可以使用数据监听器进行如下实现。
Component({ attached() { this.setData({ numberA: 1, numberB: 2, }) }, observers: { 'numberA, numberB': function (numberA, numberB) { // 在 numberA 或者 numberB 被设置时,执行这个函数 this.setData({ sum: numberA + numberB }) } } })
五.组件生命周期
1、 组件的主要生命周期
2、 组件所在页面的生命周期
六.组件间关系
Relations
抽象节点