前言
做微信小程序开发也有一年半之久了,很惭愧,期间很少用到小程序的自定义组件,最近才开始认真研究了一下,之前都是用模板来展示与封装样式。毫无疑问,比起自定义组件就是有很多的不足,最大的缺点就是不能封装js,即便有事件,也只能将它定义在Page中。
相信很多同学在研究自定义组件的时候也产生很多困惑,不知从何下手。废话不多说,这里分享一下微信小程序父子组件间如何通信。
代码
新建一个小程序项目,目录结构如下,(index页面,作为首页;components文件夹存放组件,在里面建parent父组件和child子组件)。
小程序的自定义组件需要在对应的json文件中说明为组件,即parent.json 和 child.json 的代码如下:
{
"component":true
}对应这两个js文件也要写为Component构造函数:
Component({
})在index.wxml使用和组件如下,并且需要在其index.json中声明组件的引用:
<!--index/index.wxml-->
<view>
<parent>
<child>
<view>index.html的内容</view>
</child>
</parent>
</view>{
"usingComponents": {
"parent": "/components/parent",
"child": "/components/child"
}
}下面将两个组件的全部代码贴上:
parent:
<!--components/parent.wxml-->
<view>
我是parent的内容 {{parentProps}}
<button catchtap="parentClick">parent按钮</button>
<slot />
</view>// components/parent.js
Component({
relations: {
'./child': {
type: 'child', // 关联的目标节点应为子节点
linked: function (target) {
// 每次有custom-li被插入时执行,target是该节点实例对象,触发在该节点attached生命周期之后
},
linkChanged: function (target) {
// 每次有custom-li被移动后执行,target是该节点实例对象,触发在该节点moved生命周期之后
},
unlinked: function (target) {
// 每次有custom-li被移除时执行,target是该节点实例对象,触发在该节点detached生命周期之后
}
}
},
methods:{
parentClick(){
var child = this.getRelationNodes('./child')
child[0].setData({
childProps:'hello child'
})
}
}
})child:
<!--components/child.wxml-->
<view style='padding:40rpx 0;text-align:center;'>------------分割线---------------</view>
<view>
我是child的内容 {{childProps}}
<button catchtap="childClick">child按钮</button>
<slot />
</view>// components/child.js
Component({
relations: {
'./parent': {
type: 'parent', // 关联的目标节点应为子节点
linked: function (target) {
// 每次有custom-li被插入时执行,target是该节点实例对象,触发在该节点attached生命周期之后
},
linkChanged: function (target) {
// 每次有custom-li被移动后执行,target是该节点实例对象,触发在该节点moved生命周期之后
},
unlinked: function (target) {
// 每次有custom-li被移除时执行,target是该节点实例对象,触发在该节点detached生命周期之后
}
}
},
methods:{
childClick() {
var parent = this.getRelationNodes('./parent')
parent[0].setData({
parentProps: 'hello parent'
})
}
}
})微信开发工具编译后,效果如下:
wxml中的是插槽,用于承载组件引用时提供的子节点。
这里做一下说明,parent和child组件分别要在对应的component函数中用relations字段进行关联,官方文档是这样说的:
地址:developers.weixin.qq.com/miniprogram…
重点是parent组件怎么将数据传给child,或者child组件怎么将数据传给parent,同样官方文档中有一句话如下,但是没有具体示例:
这里的custom-li对应本文的是child组件,也就说说通过getRelationNodes方法可以拿到组件已经关联了的节点,这就好办了,拿到对应的节点就可以调用setData方法设置关联节点的属性值,即nodes.setData({}),这样就达到了父子组件通信的目的,对应本文,点击页面中的按钮,可以将parent组件的"hello child"传给child,或者将child组件的"hello parent"传给parent,效果如下:
组件间的关系有四个值:parent 、 child 、 ancestor(祖先节点) 、 descendant(子孙节点)。
经试验,parent和child、ancestor和descendant是一起使用的,交叉使用无效。
至于同级组件如何通信,好像就无能为力了,官方文档也没有说明,所以在封装自定义组件的时候应避免写成同级组件。
关于behaviors
behaviors一开始误以为也和组件通信有关,但这个貌似就是用于代码共享。
最后
想说的是从事小程序开发中,还是学到很多东西的,有时候,也因为它新,并且有些东西一开始并不完善,所以网上也找没有答案,只能自己尝试和摸索,所以打算写一系列小程序的文章,记录一下遇到的坑及分享一些自己的小程序开发经验,也算是给这一年半的一个总结。