##组件间通讯与事件
一、前言
如果小程序中有可复用的UI且具有一定的功能性,就可以使用自定义组件将其封装起来。(如果仅仅只需要复用UI可使用template)下面介绍父子组件的数据传递方法,以及一个简单的组件和一个复杂的组件示例。
【由于刚开始写这篇文章的时候我还算是一个小程序的新手,自己看着官方文档研究并整理归纳的,有很多不足以及错误的地方。在经过一年的沉淀以后(虽然这一年我主要在写vue而不是小程序),我决定重新整理这篇浏览量比较大的文章,以免新手因我的文章走了弯路。】
如何实现小程序自定义组件间的通讯呢?
小程序自定义组件之间是进行相互嵌套的,嵌套之后的组件树需要经过数据进行通讯,组件树之间的数据传递是自上而下或者是自下而上的,是一个单向的数据流转,每一次数据传递都是从最上面的父级组件一层层向下传递。
小程序的组件是按照voe组件进行设计的, 每一个组件都有一个Probs接口,组件的数据都放在父级组件里面,在父级组件进行数据访问,然后通过子组件的接口向下传递,这样就把一个数据从父级组件传递到了子组件。
当子组件一内部有一个删除按钮,需要删除一组数据时,要删除的并不是子组件一中的数据,而是父组件里面的数据,这样就需要把“删除数据”这个事件传递到最外层的父级组件上。
从子组件将信息传递到父级组件是通过一种事件触发的机制来进行传递,在组件一中触发一个事件,这个事件的监听放在组件二中,就是说组件二绑定一个事件,当在组件一中触发这个事件传递参数到组件2绑定事件中,组件二通过一个方法再次触发一个事件,在组件3中也有一个事件监听,当组件二中的触发事件被监听时,在组件3中的回调方法又被执行再次发起事件的触发,再传递到组件四,组件四的事件被触发以后它的回调方法执行,变相的将数据传递到最外层的父级组件上去。
看起来是不是十分繁琐,接下来我通过一个例子来进行说明。
在自定义组件component中建立一个cources课程列表组件,cources组件里面有两个组件:外层是一个list列表组件,内层是一个item内容组件。
在最外层获取数据,然后遍历循环内层组件,假如说有两个删除按钮,当我们要删除内部的数据时我们是不能删除dome的,我们要去删除list里面保存的数据。在itme组件里面通过事件去触发父组件item里面一个事件的绑定,让父组件的回旋方法去删除数据。
首先要在list.json文件里注册cources,先注册一个标签c-item,标签的路径是./item
usingComponents": {
"c-item":"./item"
}
然后就可以在list.wxml中使用c-item标签
<view>
<c-item/>
</view>
我们在item.wxml中也使用一个view标签
<view>
<c-item/>
</view>
item子组件中的信息是由list.wxml组件传递过来的,我们传递一个值
<view>
<c-item title="xxx"/>
</view>
那 item组件如何接收呢??
我们需要在子组件的逻辑层item.js文件中的properties属性列表里面定义一个title,类型为string
properties: {
title:{
type:String
}
然后title的属性可以绑定到item.wxml文件中
<view>
{{title}}
</view>
这样list父组件传递过来的数据就能被item子组件接收。
如果一个页面级组件index要使用cources组件,一样要在index.json文件里面注册
"c-list":"../components/cources/list"
然后再将标签放在index.wxml文件中,这样页面中就会出现“xxx”,这“xxx”是通过list属性列表的wxml文件传递过来的。
子传父又是如何实现的呢??
在list.js文件中定义一个属性列表
然后再list.wxml使用标签和wx:for循环进行显示,
再在item.wxss文件中定义宽高
.item {
width: 100%;
height: 200rpx;
border-bottom:2rpx dotted gray;
font-size:60rpx
}
.del {
font-size: 60rpx;
color: red
}
界面上会出现如下图
点击叉号删除信息,但是在组件内部是无法删除掉的,要把删除的在这里插入代码片
命令发送到父组件中,让父组件删除list.js文件中的list列表。
那子组件如何触发这个事件呢?
在子组件的item.js文件中定义一个方法
methods:{
delItem(){
console.log("xx")
}
}
然后再在item.wxml中进行绑定
<text class="del" bindtap="delItem">x</text>
</view>
在由父组件接收这个事件,在父组件里使用bind绑定一个监听事件,事件名为del,回调方法为delcource。
这个回调方法定义在list.js文件中``
methods: {
delCource(e){
console.log("删除了")
}
}
然后子组件触发这个事件(triggerEvent触发list.wxml中的binddel),向父组件传递两个值,
methods: {
delItem(){
console.log(this.data.idx) this.triggerEvent("del",{id:this.data.idx}, {})
}
父组件在list.js文件中接收之后进行删除操作。