从小程序基础库版本 1.6.3 开始,小程序支持简洁的组件化编程。开发者可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。
组件详情就不介绍了,详情可以参考官方文档
[https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html]
步入正题
使用组件步骤
- 封装组件
- 父组件引入
- 父组件调用(父子通信)
1、组件封装
组件也是四个文件:xx.json,xx.js,xx.wxml,xx.wxss
要编写一个自定义组件,首先需要在 json 文件中进行自定义组件声明(将 component 字段设为 true 可这一组文件设为自定义组件):
/**
*组件中不使用组件
/
{
"component": true, // 这是一个组件
"usingComponents": {} // 是否使用组件---组件中依然可以继续使用组件
}
/**
* 组件中使用组件
* /
{
"component": true, // 这是一个组件
"usingComponents": {
"warm-prompt": "/components/warm-prompt/warm-prompt" // 组件中还使用了warm-prompt组件
}
}
接下来是JS文件
Component({
properties: {
/**
* 这里定义的变量都是父组件传过来的, innerText是父组件传过来的字段名
* type是传过来的数据格式,可以是 String,Number, array等等
* value是默认值,例如果type是String时,value可以是 '' 空字符串, 也可以是 ‘hello’
* 如果默认了hello,那么当父组件没传值时,innerText='Hhello'
* /
innerText: {
type: String,
value: 'default value',
observer: function (newVal, oldVal, changedPath) {
/**
* 属性被改变时执行的函数(可选),也可以写成在methods段中定义的方法名字符串
* 通常 newVal 就是新设置的数据, oldVal 是旧数据
* 这里通常进行父组件传值的接收
* 例如
* this.setData({
* specGroups: this.data.goodsDetail
* })
* /
}
}
},
data: {
// 这里是一些组件内部数据
someData: {
xxx: xxx,
}
},
methods: {
// 这里是一个演示向父组件传值的方法
customMethod(event){
// 定义一个对象用于传给父组件
var dates= {
id: event.currentTarget.dataset.id,
num: event.currentTarget.dataset.num
}
// 传给父级的方法
var setFunction = {}
// 使用 triggerEvent 传递给父组件 指定事件名、detail对象和事件选项
this.triggerEvent('close', dates, setFunction )
// 父组件将通过 close 拿到 dates 数据 以及 setFunctoin 方法 (setFuncton 是可选参数,可传也可不传)
}
}
})
HTML文件和wxss文件就和普通的页面一样使用
讲完了组件,说说符组件的使用
首先在要使用组件的页面的JSON文件中引入组件
{
"usingComponents": {
"warm-prompt": "/components/warm-prompt/warm-prompt" // 前面是使用的标签名,后面是组件的路径
},
"navigationBarTextStyle": "black",
"navigationBarTitleText": "首页"
}
在要使用组件的页面的中使用组件
/**
* showPrompt 是控制组件的显示/隐藏
* closePrompt 是接收组件传回来的close方法
* innerText是传给组件的值,(因为MVVM的开发方式,所以是可以动态更新修改的)
* 此处接收方法的应该是bindclose而不是close,使用格式:bind+自定义名称
* /
<warm-prompt wx:if="{
{showPrompt}}" bindclose="closePrompt" innerText='{
{innerText}}'></warm-prompt>
在要使用组件的页面的JS中接收参数
Page({
/**
* 页面的初始数据
*/
data: {
someValue: []
},
// 当自定义组件使用 triggerEvent 来传值时触发函数
closePrompt(event) {
// 自定义组件触发事件时提供的detail对象,用来获取子组件传递来的数据
var id = event.detail.id;
var num = event.detail.num ;
console.log('子组件传递来的数据 id:', id, '子组件传过来的数据num:',num);
// 其他操作...
}
})
组件的使用到此结束,接下来提几个注意点
细节注意事项
一些需要注意的细节:
- 因为 WXML 节点标签名只能是小写字母、中划线和下划线的组合,所以自定义组件的标签名也只能包含这些字符。
- 自定义组件也是可以引用自定义组件的,引用方法类似于页面引用自定义组件的方式(使用 usingComponents 字段)。
- 自定义组件和页面所在项目根目录名不能以“wx-”为前缀,否则会报错。
注意,是否在页面文件中使用 usingComponents会使得页面的 this 对象的原型稍有差异,包括:
使用 usingComponents 页面的原型与不使用时不一致,即 Object.getPrototypeOf(this) 结果不同。
使用 usingComponents 时会多一些方法,如 selectComponent 。
出于性能考虑,使用usingComponents 时, setData 内容不会被直接深复制,即 this.setData({ field: obj })后
this.data.field === obj 。(深复制会在这个值被组件间传递时发生。)