在小程序组件开发时,经常遇到子组件向父页面传值并触发父页面的方法回调。下面详细说下如何实现,子组件向父页面传值并触发父页面的方法回调。
1、自定义组件–概述
新增组件:
创建文件夹,右键-》新建component
一个组件由4个文件组成(js,json,wxml,wxss),如tabs.js,tabs.json等
申明组件
在需要使用组件的文件的json文件中的“usingComponent”,放入自定义组件,如tabs组件(通过添加键值对的形式完成,其中值为自定义组件的路径)
实际就是哪个页面要使用这个组件,就在哪个页面的json文件中申明
{ "usingComponents": { "tabs":"../../components/tabs/Tabs" }}
使用组件
在使用组件的页面使用该组件的标签,如
<tabs></tabs>
案例
1、创建自定义组件tabs
2、在tabs组件的js中完善数据部分
Component({ /** * 组件的属性列表 */ properties: { }, /** * 组件的初始数据 */ data: { tabs:[ {id:0,name:"首页",isActive:true}, {id:1,name:"原创",isActive:false}, {id:2,name:"分类",isActive:false}, {id:3,name:"关于",isActive:false} ] })
3、在tabs组件的wxml页面中创建整个组件的布局
<view class="tabs"> <view class="tabls_title"> <view wx:for="{{tabs}}" wx:key="id" class="title_item {{item.isActive?'active':''}}">{{item.name}}</view> </view> <view class="tabs_content">内容</view></view>
4、给整个tabs组件调整样式
.tabs{}.tabls_title{ display: flex; padding: 10rpx;}.title_item{ flex: 1; display: flexbox; justify-content: center; align-items: center; text-align: center;}.active{ color:red; border-bottom: 10rpx solid currentColor;}.tabs_content{}
5、在要使用该组件的页面的json文件中申明该组件
{ "usingComponents": { "tabs":"../../components/tabs/Tabs" }}
6、在要使用该组件的页面的wxml文件中使用该组件
<tabs></tabs>
2、自定义组件–组件的回调方法
页面的回调方法是放在组件js文件中的page里,与data同级。
而页面的回调方法是放在组件js文件中的methods对象里
具体绑定事件的回调函数的一些问题
绑定点击事件需要在methods中绑定
获取被点击的对象的索引
获取原数组
对数组循环,给每一个循环项的选中属性改为false
给当前的所影响添加激活选中效果就可以了
methods: { //点触view的方法 tapview:function (e) { //获取索引 const {index}=e.currentTarget.dataset; //获取data的原数组 //对复杂类型进行解构的时候,复制了一分变量的引用,等同于 //let tabs=this.data.tabs let {tabs}=this.data; //循环该数组[].forEach 遍历数组 修改了v,也会导致源数组被修改 tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false); //修改数组值 this.setData({ tabs//实际执行赋值 } ) } }
对复杂类型进行解构的时候,复制了一分变量的引用,等同于直接获取tabs
/** * 组件的方法列表 */ methods: { //点触view的方法 tapview:function (e) { //获取索引 const {index}=e.currentTarget.dataset; //获取data的原数组 let mytabs=this.data.tabs; //循环该数组[].forEach 遍历数组 修改了v,也会导致源数组被修改 mytabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false); //修改数组值 this.setData({ tabs:mytabs } ) } }})
3、自定义组件–父组件向子组件传递数据
父组件向子组件传递数据是通过标签属性的方式来传递的,
并在子组件上进行接收
然后把这个数据直接当做data中的数据直接使用即可
案例如下
1、先在父组件页面上设置属性myPro
mypage.wxml文件
<tabs myPro="122234"></tabs>
2、再在自定义组件tabs的Component的properties中创建myPro对象的数据类型和值
tabs.js文件
Component({ /** * 组件的属性列表,里面存放要从父组件中接收的数据 */ properties: { //要接受的数据的名称 myPro:{ //type要接受的数据的类型 type:String, //value要接受的数据的默认值 value:"" } })
3、在自定义组件的wxml文件中直接使用这个属性对象的值
tabs.wxml文件
<view>{{myPro}}</view>
完整的案例
1、应用页面的js文件
mypage.js
Page({ /** * 页面的初始数据 */ data: { tabs:[ {id:0,name:"首页",isActive:true}, {id:1,name:"原创",isActive:false}, {id:2,name:"分类",isActive:false}, {id:3,name:"关于",isActive:false} ] })
2、父组件创建tabs属性,并从自己的js文件中拿数据tabs数组,从而通过tabs属性向子组件传递数据
mypage.wxml
<tabs tabs="{{tabs}}"></tabs>
3、子组件通过proerties对象拿到父组件传来的数据,并定义数据类型和值
tabs.js文件
Component({ /** * 组件的属性列表,里面存放要从父组件中接收的数据 */ properties: { //要接受的数据的名称 tabs:{ //类型是一个数组 type:Array, //值是一个空数组 value:[] } })
4、在子组件的wxml文件中拿到子组件js里传来的数据,循序
tabs.wxml
<view class="tabs"> <view class="tabls_title"> <view wx:for="{{tabs}}" wx:key="id" class="title_item {{item.isActive?'active':''}}" bindtap="tapview" data-index="{{index}}">{{item.name}}</view> </view> <view class="tabs_content">内容</view></view>
漏了关键代码找不到了,以后再学吧
4、自定义组件–子组件向父组件传递数据
触发父组件中的自定义事件,同时传递数据给父组件
this.triggerEvent("父组件自定义事件的名称",要传递的参数) 却 this.triggerEvent("itemChange",this.data.tabs)
子组件向父组件传递数据是通过事件的方式传递,在子组件的标签上加入一个自定义事件
<tabs tabsP="{{tabs}}" binditemChange="itemChange"></tabs> 或者 <tabs tabsP="{{tabs}}" bind:itemChange="itemChange"></tabs>
父页面里回调接受参数
itemChange(e) { console.log(e.detail) } 或者 解构传参数 itemChange({detail}) { console.log(detail) }