在小程序组件开发时,经常遇到子组件向父页面传值并触发父页面的方法回调。下面详细说下如何实现,子组件向父页面传值并触发父页面的方法回调。
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)
}


