什么是微信小程序的自定义组件以及意义
自定义组件,类似于Vue中的组件概念(事件通信机制非常类似),将页面内的一些功能模块抽象成自定义组件,以便在不同的页面中重复使用,也可以将复杂的页面拆分成多个低耦合的模块,有助于代码的维护。
创建自定义组件
自定义组件和页面类似,也是需要四个部分组成。wxss,wxml,js,json
在自定义组件的js文件中,需要使用Component()来注册组件,并提供组件的属性定义、内部数据和自定义方法。
属性和内部数据都是被用于wxml的渲染,其中属性值是可由外部组件传入的。
如何使用自定义组件
怎样在一个具体的页面中使用自定义组件呢?首先,我们需要告诉页面我们引用了哪一个自定义组件,也就需要在页面的json中进行引用声明。如下所示,提供每个自定义组件的标签名以及对应的自定义组件的文件路径。
{
"usingComponents": {
"component-tag-name": "path/to/the/custom/component"
}
}
然后,我们在页面的wxml中就可以像使用基础组件一样使用自定义组件。节点名即自定义组件的标签名,节点属性即传递给组件的属性值。如下所示:
<view>
<!-- 以下是对一个自定义组件的引用 -->
<component-tag-name inner-text="Some text"></component-tag-name>
</view>
注意事项
在组件wxss中不应该使用ID选择器、属性选择器和标签选择器
因为wxml节点标签名只能是小写字母,中划线和下划线组成,所以自定义组件也只能包含这些这些字符。
在properties定义段中,属性名采用驼峰写法(propertyName);在wxml中,指定属性值的时候则对应使用连字符写法(component-tag-name property-name="attr name"),应用于数据绑定的时候采用驼峰写法(attr="propertyName")
使用this.data可以获取内部数据和属性值,但不要直接修改它们,应该使用setData修改
组件模板
组件模板与组件数据结合后生成的节点树,将被插入到组件的引用位置上。
在组件模板中可以提供一个<slot>节点,用于承载组件引用时提供的子节点。
如下所示:
<!-- 组件模板 -->
<view class="wrapper">
<view>这里是组件的内部节点</view>
<slot></slot>
</view>
<!-- 引用组件的页面模版 -->
<view>
<component-tag-name>
<!-- 这部分内容将被放置在组件 <slot> 的位置上 -->
<view>这里是插入到组件slot中的内容</view>
</component-tag-name>
</view>
当然,也可以使用多个slot,如果使用多个slot的时候,组件需要指定slot的name属性,然后在使用组件的时候,使用slot属性将节点插入到不同的slot中上。
官方的例子如下:
<!-- 组件模板 -->
<view class="wrapper">
<slot name="before"></slot>
<view>这里是组件的内部细节</view>
<slot name="after"></slot>
</view>
<!-- 引用组件的页面模版 -->
<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生效,编写组件样式的时候,需要特别注意:
- 继承样式。如font、color,会从组件外继承到组件内。
- 除了继承样式外,app.wxss中的样式、组件所在页面的样式对自定义组组件无效。
- 子选择器(.a>.b)只能用于view组件与其子节点之间,用于其他组件可能导致非预期的结果
Component构造器
ComPonent构造器可用于定义组件,调用Component构造器的时候可以指定组件的属性、数据、方法等
组件间通信与事件
组件之间的基本通信方法有以下几种:
- wxml数据绑定:用于父组件向子组件的指定属性设置数据,仅能设置JSON兼容数据
- 事件:用于子组件向父组件传递数据,可以传递任何数据
- 如果以上两种方式还不足以满足需求,那么父组件还可以通过this.selectComponent方法获取子组件的实例对象,这样就可以直接访问组件中的任意数据和方法了。
下面就介绍通过事件进行通信
自定义组件触发事件
自定义组件触发事件的时候,需要通过triggerEvent方法,指定事件名称、detail对象和事件选项。官方例子如下:
<!-- 在自定义组件中 -->
<button bindtap="onTap">点击这个按钮将触发“myevent”事件</button>
Component({
properties: {}
methods: {
onTap: function(){
var myEventDetail = {} // detail对象,提供给事件监听函数
var myEventOption = {} // 触发事件的选项
this.triggerEvent('myevent', myEventDetail, myEventOption)
}
}
})
其中触发事件的选项包括:
调用组件,监听事件
引用组件的页面可以监听这些事件。如下:
<!-- 当自定义组件触发“myevent”事件时,调用“onMyEvent”方法 -->
<component-tag-name bindmyevent="onMyEvent" />
<!-- 或者可以写成 -->
<component-tag-name bind:myevent="onMyEvent" />
Page({
onMyEvent: function(e){
e.detail // 自定义组件触发事件时提供的detail对象
}
})