官网上描述:
$broadcast
$broadcast事件是由父组件发起,所有子组件都会收到此广播事件,除非事件被手动取消。事件广播的顺序为广度优先搜索顺序。
$emit
$emit与$broadcast正好相反,事件发起组件的所有祖先组件会依次接收到$emit事件。
$invoke
$invoke是一个页面或组件对另一个组件中的方法的直接调用,通过传入组件路径找到相应的组件,然后再调用其方法。
$emit例子:
子组件中选择平台(‘全平台’, ‘爱奇艺’, ‘腾讯’, ‘优酷’),通知父组件此时选中的平台是谁,用来通知父组件控制指标是否可以被选中(当为全平台时,不可选中资源等级)
子组件代码:
<picker @change="bindPickerChange" value="{{platformIndex}}" range="{{platformArray}}">
<view style="display: flex;align-items: center" >
<view>{{platformArray[platformIndex]}}</view>
<view class="iconfont icon-xiajiantou" style="margin-left:10rpx;font-size: 30rpx;color: gray" ></view>
</view>
</picker>
methods = {
bindPickerChange (e) {
console.log('切换平台')
this.platformIndex = e.detail.value
this.$emit('platformChoose',this.platformArray[this.platformIndex]);
}
}
data = {
platformArray: ['全平台', '爱奇艺', '腾讯', '优酷'],
platformIndex: 0,
};
父组件代码:
events = {
platformChoose(platform,event){
console.log('此时子组件选择的平台是',platform)
this.platform = platform
}
}
当切换子组件中当平台时:
当切换子组件中的平台为全平台,在父组件中选择指标会提示:
$invoke例子:
子组件中调用接口获取列表数据,负责控制页面正在加载的进度是否显示,用户在父组件内滑到底部触发加载下一页数据,在子组件页面显示
子组件代码:
<block wx:for="{{filmData}}" wx:for-item="category" wx:key="*this">
<view style="height:100px">{{category.name}}</view>
</block>
<view class="weui-loadmore" hidden="{{isHideLoadMore || filmData.length===0}}">
<view class="weui-loading"></view>
<view class="weui-loadmore__tips">正在加载</view>
</view>
data = {
page: 1,
isHideLoadMore: true,
totalPage: 1,
filmData: []
}
onReachBottomCom() {
this.isHideLoadMore = false;
++this.page;
if (this.page > (this.totalPage / 10 + 1)) {
this.isHideLoadMore = true;
this.$apply();
wx.stopPullDownRefresh();
} else {
this.getlistData(); //获取下一页数据
}
};
async getlistData () {
try {
let apiParams = JSON.stringify({
'url': '/listData',
'method': 'POST',
'params': {
// *** 其他参数
'page': this.page,
'pageLineCount': 10,
}
})
let res = await api.api_post(apiParams)
console.log('listData 列表',res)
if (!res.data.hasOwnProperty('status')) {
let data = this.filmData.concat(res.data.listData)
this.filmData = data
this.totalPage = res.data.totalPage
this.$apply()
}
} catch (e) {
console.log(e)
}
};
父组件代码:
onReachBottom() {
this.$invoke('子组件名称', 'onReachBottomCom', '');
};
app.wepy:
'window': {
'onReachBottomDistance': 400,
}
当在父组件内触底刷新时:
当在父组件内调用子组件获取列的方法后,得到下一页数据:
$broadcast例子:
父组件某个变量发生改变,通知所有子组件执行某个方法,例当组件切换tabs时,当切换为全网大盘时,所有图表重新刷新显示:
父组件代码:
<view class="home page">
<view class="tabs-change">
<view class="tabs_item {{chooseShowPage==='全网大盘'?'':'click-color1'}}" bindtap="typeChange('全网大盘')" >
全网大盘
</view>
<view class="tabs_item {{chooseShowPage==='排行榜'?'':'click-color1'}}" bindtap="typeChange('排行榜')">
排行榜
</view>
</view>
<i-toast id="toast" />
<grail :chooseShowPage.sync="chooseShowPage" :tvType="tvType" wx:if="{{chooseShowPage==='全网大盘'}}"/>
<rankingList :tvType="tvType" wx:if="{{chooseShowPage==='排行榜'}}"/>
</view>
methods = {
typeChange (type) {
this.chooseShowPage = type
this.updateShowPage()
}
};
async updateShowPage () {
try {
await new Promise(resolve => {
setTimeout(() => {
resolve('async await test...')
}, 1000)
})
this.$broadcast('chooseShowPage', this.chooseShowPage) //必须是异步执行广播事件,原理和小程序页面刷新和canvas重绘的先后机制有关,否则图表不显示
this.$apply()
} catch (e) {
console.log(e)
}
}
子组件代码:
events = {
chooseShowPage (newValue) {
if (newValue==='全网大盘') {
chart.setOption(this.option)
}
}
}